What is Docker?
Docker is an open-source containerization platform that allows developers to package applications along with all their dependencies into lightweight, portable containers. Containers can run on any Docker-supported environment, ensuring that "it works on my machine" means "it works everywhere."
Why Use Docker?
- Environment Consistency: Development, testing, and production environments are identical, eliminating the "works on my machine" problem
- Lightweight and Fast: Compared to traditional VMs, containers start in seconds and consume fewer resources
- Isolation: Each container has its own filesystem, network, and process space
- Portability: Build once, run anywhere — Linux, macOS, Windows, and cloud platforms
- Easy to Scale: Combine with Docker Compose or Kubernetes to manage multiple services effortlessly
Docker vs Virtual Machines (VMs)
| Feature | Docker Container | Virtual Machine |
|---|---|---|
| Startup time | Seconds | Minutes |
| Resource usage | Shares host kernel, very lightweight | Requires full OS, heavy resource usage |
| Image size | Typically tens to hundreds of MB | Typically several GB |
| Isolation level | Process-level isolation | Hardware-level isolation |
| Best for | Microservices, CI/CD, rapid deployment | Full OS requirements or high isolation |
Core Concepts
Before getting started with Docker, let's understand a few core concepts:
Image
An image is a read-only template that contains everything needed to run an application: code, runtime, system tools, libraries, and configuration files. Think of an image as a "snapshot" of your application.
Container
A container is a running instance of an image. You can create multiple containers from the same image, and each container is isolated from the others. Containers can be started, stopped, and deleted without affecting the underlying image.
Dockerfile
A Dockerfile is a text file that defines the steps to build an image. It is like a recipe that tells Docker what to do step by step.
Registry
A registry is where images are stored and distributed. The most commonly used is Docker Hub. You can also use GitHub Container Registry or host a private registry.
Volume
A volume is a persistent storage space managed by Docker, used to save data generated by containers. Data in volumes persists even after the container is deleted.
Installing Docker
macOS
Install Docker Desktop using Homebrew:
Loading...
After installation, launch the Docker Desktop application.
Ubuntu / Debian
Loading...
Verify Installation
Loading...
Basic Commands
Image Operations
Loading...
Container Operations
Loading...
Common docker run Flags
Loading...
System Cleanup
Loading...
Writing a Dockerfile
A Dockerfile defines every step of building an image. Here is an example for a Node.js application:
Basic Example
Loading...
Common Instructions
| Instruction | Description |
|---|---|
FROM | Specify the base image |
WORKDIR | Set the working directory for subsequent instructions |
COPY | Copy files from the host into the image |
RUN | Execute a command during the build process |
ENV | Set environment variables |
EXPOSE | Declare the port the container will use (for documentation) |
CMD | Default command to run when the container starts |
ENTRYPOINT | Entry program when the container starts (harder to override) |
ARG | Define build-time variables |
VOLUME | Declare mount points |
Multi-stage Build
Multi-stage builds significantly reduce the final image size by separating build tools from the runtime environment:
Loading...
Benefit: Build-stage tools (dev dependencies, source code) are not included in the final image, significantly reducing its size.
.dockerignore File
Similar to .gitignore, .dockerignore tells Docker which files to exclude during the build:
node_modules
.next
.git
.gitignore
*.md
.env
.env.local
docker-compose.yml
Docker Compose
Docker Compose lets you define and manage multiple container services with a single YAML file. It is ideal for scenarios where multiple services need to run simultaneously (e.g., application + database + reverse proxy).
docker-compose.yml Example
Loading...
Common Compose Commands
Loading...
Common Configuration Options
Loading...
Networking
Docker containers communicate with each other through networks. Docker Compose automatically creates a default network for all services in the same project.
Basic Network Commands
Loading...
Container-to-Container Communication
In Docker Compose, services can communicate with each other directly using service names as hostnames:
Loading...
From the app container, you can connect to the database at database:5432.
Volumes
Containers are "stateless" by default — data is lost when a container is deleted. Use volumes to persist data.
Volume Types
Loading...
Volume Management Commands
Loading...
Common Deployment Workflow
Manual Deployment to a VPS
Loading...
Deploying with Docker Hub
Loading...
Debugging Tips
View Container Status and Logs
Loading...
Enter a Container for Debugging
Loading...
Common Troubleshooting
Container stops immediately after starting:
Loading...
Port conflict:
Loading...
Insufficient disk space:
Loading...
Best Practices
- Use Alpine Images: Choose
node:20-alpineovernode:20to reduce image size by hundreds of MB - Use Multi-stage Builds: Separate build and runtime environments to minimize image size
- Never Store Secrets in Images: Use environment variables or Docker Secrets to manage passwords and keys
- Use .dockerignore: Prevent unnecessary files from being packaged into the image
- Pin Image Versions: Use
node:20-alpineinstead ofnode:latestto ensure reproducible builds - One Service per Container: Follow the single responsibility principle — run only one main process per container
- Leverage Caching: Place infrequently changing steps (like installing dependencies) earlier in the Dockerfile
- Set Health Checks: Use the
HEALTHCHECKinstruction to monitor container health - Use Restart Policies: Set
restart: unless-stoppedto ensure services recover automatically - Clean Up Regularly: Use
docker system pruneto remove unused resources and free disk space