Docker Comprehensive Guide
Complete guide to Docker: Images, Containers, Lifecycle, Volumes, Networks, and Best Practices
What is Docker?
Docker is a platform for developing, shipping, and running applications using containerization. Containers package an application with all its dependencies, ensuring it runs consistently across different environments.
Key Benefits
- ✓ Consistent environments
- ✓ Isolation and security
- ✓ Resource efficiency
- ✓ Easy scaling
- ✓ Fast deployment
Core Concepts
- • Image: Read-only template
- • Container: Running instance
- • Volume: Persistent storage
- • Network: Communication layer
- • Dockerfile: Build instructions
Docker Architecture
┌─────────────────────────────────────────┐
│ Docker Architecture │
├─────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Client │───▶│ Daemon │ │
│ │ (CLI) │ │ (dockerd) │ │
│ └──────────────┘ └──────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────────────┐ │
│ │ │ Containers │ │
│ │ │ Images │ │
│ │ │ Volumes │ │
│ │ │ Networks │ │
│ │ └──────────────┘ │
│ │ │
│ └───────────▶ Registry │
│ (Docker Hub) │
└─────────────────────────────────────────┘
Docker Client: CLI tool to interact with Docker
Docker Daemon: Background service managing containers
Docker Registry: Repository for storing images (Docker Hub, private registries)
Docker Images
A Docker image is a read-only template used to create containers. Images are built from Dockerfiles and consist of multiple layers that are stacked on top of each other.
Image Layers
┌─────────────────────────┐
│ Application Layer │ ← Your app code
├─────────────────────────┤
│ Dependencies Layer │ ← npm packages, pip packages
├─────────────────────────┤
│ Runtime Layer │ ← Node.js, Python, etc.
├─────────────────────────┤
│ OS Layer │ ← Alpine, Ubuntu, etc.
└─────────────────────────┘
Image Lifecycle
1. Build
Create an image from a Dockerfile
2. Tag
Tag an image with a name and version
3. Push
Upload image to a registry
4. Pull
Download image from a registry
5. Remove
Delete unused images
Common Image Commands
docker images
docker inspect image:tag
docker history image:tag
docker save -o image.tar image:tag
docker load -i image.tar
Docker Containers
A container is a running instance of an image. Containers are isolated, lightweight, and share the host OS kernel.
Container Lifecycle
Created → Running → Paused → Stopped → Removed
│ │ │ │ │
│ │ │ │ └─ docker rm
│ │ │ └─ docker stop
│ │ └─ docker pause/unpause
│ └─ docker start
└─ docker create
Container States
- Created: Initialized but not started
- Running: Currently executing
- Paused: Temporarily suspended
- Stopped: Exited or stopped
- Removed: Deleted from system
Container Properties
- • Unique ID and name
- • Isolated filesystem
- • Network interface
- • Resource limits (CPU, memory)
- • Environment variables
Container Commands
Create & Run
-d: detached mode, --name: container name
Interactive Container
-it: interactive terminal
With Port Mapping
-p host:container maps port 8080 to container's port 80
With Environment Variables
-e: set environment variable
Management Commands
docker ps
docker ps -a
docker stop container_name
docker start container_name
docker rm container_name
docker logs container_name
docker exec -it container_name /bin/bash
Dockerfile
A Dockerfile is a text file containing instructions to build a Docker image. Each instruction creates a new layer.
Common Dockerfile Instructions
FROM
Sets the base image
WORKDIR
Sets working directory
COPY / ADD
Copies files into image
COPY . .
RUN
Executes commands during build
RUN apt-get update && apt-get install -y curl
ENV
Sets environment variables
ENV PORT=3000
EXPOSE
Documents which port the app listens on
CMD / ENTRYPOINT
Defines default command to run
ENTRYPOINT ["node", "server.js"]
Example Dockerfile
# Node.js Application Dockerfile
FROM node:18-alpine
# Set working directory
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy application code
COPY . .
# Set environment variables
ENV NODE_ENV=production
ENV PORT=3000
# Expose port
EXPOSE 3000
# Health check
HEALTHCHECK --interval=30s --timeout=3s \
CMD node healthcheck.js
# Run application
CMD ["node", "server.js"]
Multi-stage Build Example
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
EXPOSE 3000
CMD ["node", "dist/server.js"]
Docker Volumes
Volumes provide persistent storage for containers. Data in volumes persists even after containers are removed.
Volume Types
Named Volumes
Managed by Docker, stored in Docker's directory
Bind Mounts
Mount host directory into container
tmpfs Mounts
Stored in host memory (temporary)
Volume Commands
Create Named Volume
Use Volume in Container
Bind Mount
Volume Management
docker volume ls
docker volume inspect mydata
docker volume rm mydata
docker volume prune
Volume Use Cases
- • Database data: Persist database files across container restarts
- • Configuration files: Share configs between host and container
- • Application logs: Store logs outside container
- • Source code: Mount code for development (bind mount)
- • Shared data: Share data between multiple containers
Docker Networks
Docker networks enable communication between containers and with external networks. Containers can be isolated or connected.
Network Types
Bridge Network (Default)
Isolated network for containers on same host
docker run --network=mynetwork nginx
Host Network
Container uses host's network directly
None Network
No network access (complete isolation)
Overlay Network
Multi-host networking for Swarm clusters
Network Commands
docker network ls
docker network create mynetwork
docker network inspect mynetwork
docker network connect mynetwork container
docker network disconnect mynetwork container
docker network rm mynetwork
Container Communication
# Create network
docker network create app-network
# Run containers on same network
docker run -d --name web --network app-network nginx
docker run -d --name db --network app-network postgres
# Containers can communicate using container names
# From web container: curl http://db:5432
Docker Compose
Docker Compose is a tool for defining and running multi-container Docker applications using a YAML file.
docker-compose.yml Structure
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
volumes:
- ./app:/app
depends_on:
- db
networks:
- app-network
db:
image: postgres:14
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
- db-data:/var/lib/postgresql/data
networks:
- app-network
volumes:
db-data:
networks:
app-network:
driver: bridge
Compose Commands
Start Services
-d: detached mode
Stop Services
View Logs
Scale Services
Build Images
Docker Best Practices
Image Best Practices
✓ Use Multi-stage Builds
Reduce final image size by using separate build and runtime stages
✓ Use .dockerignore
Exclude unnecessary files from build context
.git
*.log
✓ Use Specific Tags
Avoid using 'latest' tag in production
✓ Minimize Layers
Combine RUN commands to reduce layers
curl && rm -rf /var/lib/apt/lists/*
Security Best Practices
✓ Run as Non-root User
USER appuser
✓ Scan Images for Vulnerabilities
✓ Use Secrets Management
Never hardcode secrets in Dockerfiles
✓ Limit Container Resources
Performance Best Practices
✓ Use .dockerignore
Reduce build context size
✓ Leverage Build Cache
Order Dockerfile instructions from least to most frequently changing
✓ Use Alpine Images
Smaller base images reduce image size