Learn Docker from the basics to practical application. Understand Docker containers, create Dockerfiles, manage multi-container applications with Docker Compose, and explore essential Docker commands.
Developing an application is one thing. Making sure it runs consistently across different environments is another challenge.
Have you ever developed an application that worked perfectly on your computer but failed when deployed to another server? Differences in operating systems, dependencies, libraries, runtime versions, and configurations can cause unexpected problems.
This is one of the problems Docker was designed to solve.
Docker is a platform that allows developers to build, package, distribute, and run applications inside lightweight, isolated environments called containers.
Instead of manually installing and configuring application dependencies on every server, Docker allows you to package the application and its required environment into a portable container image.
Whether you are a web developer, backend engineer, DevOps professional, or system administrator, understanding Docker can significantly simplify your development and deployment workflow.
Let's explore how Docker works and how to use its most important components.
Docker is an open-source containerization platform used to develop, ship, and run applications inside containers.
A Docker container includes the application and the dependencies required to run it, such as libraries, runtime environments, and configuration files.
Containers share the host operating system's kernel while maintaining process and resource isolation. This makes them generally more lightweight than traditional virtual machines.
Before working with Docker, understand these four fundamental concepts:
Docker Image: A read-only template containing the application and everything needed to run it.
Docker Container: A running or stopped instance of a Docker image.
Dockerfile: A text file containing instructions for building a Docker image.
Docker Compose: A tool for defining and managing multi-container applications using a YAML configuration file.
A Dockerfile is a text-based configuration file containing instructions that Docker uses to build an application image.
It defines the base image, working directory, dependencies, application files, environment settings, and startup command.
Instead of manually preparing an application environment every time, you can describe the complete build process in a Dockerfile.
Let's consider a simple Node.js application.
Create a file named Dockerfile:
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
| Instruction | Purpose |
|---|---|
| FROM | Defines the base image. |
| WORKDIR | Sets the working directory. |
| COPY | Copies files into the image. |
| RUN | Executes commands during image building. |
| EXPOSE | Documents the application port. |
| ENV | Defines environment variables. |
| CMD | Defines the default command when the container starts. |
| ENTRYPOINT | Defines the main executable for the container. |
For example, FROM node:22-alpine selects a lightweight Node.js base image.
RUN npm install installs the dependencies, while CMD ["npm", "start"] defines the default startup command.
Build the image:
docker build -t my-node-app .
Run the container:
docker run -d -p 3000:3000 --name my-app my-node-app
Your application can now be accessed through:
http://localhost:3000
Writing Dockerfiles manually is useful for learning, but developers often need to create configurations for different languages, frameworks, and application environments.
The Dockerfile Generator from DevUtilityKits helps simplify this process by providing a convenient way to generate Dockerfile configurations.
Explore: Dockerfile Generator
Docker Compose is a tool used to define and manage multi-container Docker applications.
Modern applications often depend on multiple services. For example, a typical web application might require:
Managing each container individually can become complicated.
Docker Compose simplifies this process by allowing you to define multiple services in a single YAML configuration file, usually named compose.yaml or docker-compose.yml.
Let's create a simple application with a web service and a Redis service.
Create a file named compose.yaml:
services:
web:
image: nginx:alpine
ports:
- "8080:80"
depends_on:
- redis
redis:
image: redis:alpine
This configuration defines two services:
web: Runs an Nginx container and exposes port 8080 on the host.
redis: Runs a Redis container that the web service can communicate with through the Compose network.
Start all services:
docker compose up -d
View running services:
docker compose ps
View service logs:
docker compose logs
Stop services:
docker compose stop
Stop and remove containers and networks:
docker compose down
Rebuild and start services:
docker compose up -d --build
Docker Compose is particularly useful for local development, testing environments, and applications that depend on multiple services.
Creating a Compose configuration requires understanding service definitions, ports, volumes, networks, environment variables, and dependencies.
If you want to create a configuration more efficiently, try the free Docker Compose Generator.
Explore: Docker Compose Generator
Docker provides a command-line interface (CLI) for managing images, containers, networks, volumes, and application deployments.
Here are some of the most frequently used Docker commands.
Check the Docker version:
docker --version
Display detailed system information:
docker info
Display Docker help:
docker --help
List available images:
docker images
Download an image:
docker pull nginx
Build an image:
docker build -t myapp .
Remove an image:
docker rmi myapp
List running containers:
docker ps
List all containers:
docker ps -a
Start a container:
docker start my-container
Stop a container:
docker stop my-container
Restart a container:
docker restart my-container
Remove a container:
docker rm my-container
View container logs:
docker logs my-container
Access a running container's shell:
docker exec -it my-container sh
List Docker networks:
docker network ls
Create a network:
docker network create my-network
Inspect a network:
docker network inspect my-network
Remove a network:
docker network rm my-network
List volumes:
docker volume ls
Create a volume:
docker volume create my-data
Inspect a volume:
docker volume inspect my-data
Remove a volume:
docker volume rm my-data
Docker volumes are useful for preserving application data independently of the lifecycle of individual containers.
Docker has many commands and options. Remembering the correct syntax for every operation can be challenging, particularly when working with advanced configurations.
For example, running a container with port mappings, environment variables, volume mounts, restart policies, and custom networks requires the correct combination of command-line options.
The Docker Command Generator from DevUtilityKits helps developers create Docker commands more conveniently.
Explore: Docker Command Generator
It provides a convenient starting point for constructing Docker CLI commands without having to remember every option manually.
Always review generated commands before executing them, especially when they involve deleting containers, removing volumes, or changing production environments.
Docker makes application deployment easier, but proper configuration is essential for reliable production environments.
Consider these best practices:
Use Lightweight Base Images: Choose appropriate minimal images to reduce image size and unnecessary dependencies.
Avoid Running as Root: Use a dedicated non-root user inside application containers whenever possible.
Use Environment Variables: Keep environment-specific configuration outside application images. Never bake secrets into images.
Use Persistent Volumes: Store important application data outside the container's writable layer.
Optimize Dockerfiles: Use multi-stage builds and Docker build cache effectively.
Keep Images Updated: Regularly update base images and dependencies to address security vulnerabilities.
Configure Resource Limits: Monitor and manage CPU and memory consumption.
Use Health Checks: Configure health checks to monitor application availability.
Protect Production Secrets: Use appropriate secret-management mechanisms rather than storing passwords and API keys directly in configuration files.
Although Docker and Docker Compose work together, they serve different purposes.
| Feature | Docker CLI | Docker Compose |
|---|---|---|
| Primary purpose | Manage Docker resources | Manage multi-container applications |
| Configuration | Individual commands | YAML configuration |
| Container management | Yes | Yes |
| Image management | Yes | Through service definitions and Docker |
| Multi-service applications | Manual coordination | Centralized management |
| Typical use | Build, run, inspect and manage containers | Start and manage application services together |
Which should you use?
Use Docker CLI when you need direct control over individual images, containers, networks, and volumes.
Use Docker Compose when your application requires multiple services that should be configured and managed together.
In real-world development and DevOps workflows, both are commonly used together.
Docker has become an important technology in modern software development, application deployment, and DevOps workflows.
Understanding Docker images, containers, Dockerfiles, Docker Compose, and essential Docker commands provides a strong foundation for building and managing containerized applications.
Whether you are developing a simple Node.js application, deploying a backend API, managing databases, or building a multi-service environment, Docker can make your workflow more consistent and efficient.
You don't have to memorize every Docker instruction or command. Practical utilities can help you create configurations and commands faster.
DevUtilityKits provides convenient online utilities designed to simplify everyday development and infrastructure tasks.
More Free Developer Tools to explore 150+ Free Online Developer Tools designed to save time and simplify everyday technical work.
Build smarter. Deploy faster. Simplify your DevOps workflow with Docker and DevUtilityKits.