This comprehensive guide covers advanced Docker container operations, from lifecycle management to production deployment strategies. It builds upon the Docker Quickstart guide.
Container Lifecycle Management
Container States
Containers transition through several states during their lifecycle:
┌─────────────────────────────────────────────────────────────────┐
│ Container Lifecycle │
├─────────────────────────────────────────────────────────────────┤
│ Created → Running → Paused → Stopped → Removed │
│ ↑ ↓ ↑ ↑ ↑ │
│ └─────────┴─────────┴─────────┴─────────┘ │
└─────────────────────────────────────────────────────────────────┘
Advanced Container Operations
Creating Containers
# Create container without starting
docker create --name webserver nginx:latest
# Create with resource limits
docker create --name limited-app \
--memory="512m" \
--cpus="1.0" \
--storage-opt size=10G \
nginx:latest
# Create with environment variables
docker create --name app \
-e NODE_ENV=production \
-e DATABASE_URL=postgres://localhost/mydb \
node:16-alpine
Container Inspection
# Detailed container information
docker inspect webserver
# Get specific information using format
docker inspect --format='{{.State.Status}}' webserver
docker inspect --format='{{.NetworkSettings.IPAddress}}' webserver
docker inspect --format='{{range .Mounts}}{{.Source}}:{{.Destination}}{{end}}' webserver
# Container resource usage
docker stats webserver
# Real-time container events
docker events --filter container=webserver
Container Process Management
# List processes in container
docker top webserver
# Execute commands in running container
docker exec webserver ls -la /etc
# Interactive shell in container
docker exec -it webserver /bin/bash
# Execute as specific user
docker exec -u root -it webserver /bin/bash
# Execute with environment variables
docker exec -e VAR=value webserver env
Advanced Networking
Network Types
Bridge Networks (Default)
# Create custom bridge network
docker network create --driver bridge mybridge
# Run container on custom bridge
docker run -d --name web1 --network mybridge nginx
docker run -d --name web2 --network mybridge nginx
# Containers can communicate by name
docker exec web1 ping web2
Host Networks
# Use host networking (container shares host network stack)
docker run -d --network host nginx
# No port mapping needed - container uses host ports directly
None Networks
# Container with no network access
docker run -d --network none alpine sleep 3600
Overlay Networks (Multi-host)
# Create overlay network (requires Docker Swarm)
docker network create --driver overlay --attachable myoverlay
# Run containers on different hosts using same network
docker run -d --name service1 --network myoverlay alpine
Advanced Network Configuration
Custom Network with Subnet
# Create network with custom subnet
docker network create --driver bridge \
--subnet=172.20.0.0/16 \
--ip-range=172.20.240.0/20 \
--gateway=172.20.0.1 \
custom-net
# Run container with static IP
docker run -d --name web \
--network custom-net \
--ip 172.20.0.10 \
nginx
Network Aliases
# Create container with network alias
docker run -d --name db \
--network mynetwork \
--network-alias database \
--network-alias mysql-server \
mysql:8.0
# Other containers can connect using alias
docker run -d --name app \
--network mynetwork \
-e DB_HOST=database \
myapp:latest
Port Publishing Strategies
# Publish specific port
docker run -p 8080:80 nginx
# Publish all exposed ports to random host ports
docker run -P nginx
# Publish to specific interface
docker run -p 127.0.0.1:8080:80 nginx
# Publish UDP port
docker run -p 8080:80/udp nginx
# Multiple port mappings
docker run -p 80:80 -p 443:443 -p 8080:8080 nginx
Volume Management and Data Persistence
Volume Types Comparison
Type | Use Case | Performance | Portability | Management |
---|---|---|---|---|
Named Volumes | Database data, shared data | High | High | Docker managed |
Bind Mounts | Development, config files | Medium | Low | Host managed |
tmpfs | Temporary data, secrets | Highest | N/A | Memory only |
Named Volumes
# Create volume with driver options
docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.1.1,rw \
--opt device=:/path/to/dir \
nfs-volume
# Use volume with specific mount options
docker run -d --name app \
--mount source=myvolume,target=/data,readonly \
alpine
# Backup volume data
docker run --rm \
-v myvolume:/data \
-v $(pwd):/backup \
alpine tar czf /backup/backup.tar.gz /data
# Restore volume data
docker run --rm \
-v myvolume:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/backup.tar.gz -C /
Bind Mounts Best Practices
# Read-only bind mount
docker run -d --name web \
--mount type=bind,source=/host/config,target=/app/config,readonly \
nginx
# Bind mount with propagation
docker run -d --name app \
--mount type=bind,source=/host/data,target=/data,bind-propagation=shared \
alpine
# Bind mount with SELinux labels (Linux)
docker run -d --name app \
-v /host/data:/data:Z \
alpine
tmpfs Mounts for Security
# Mount secrets in memory
docker run -d --name app \
--tmpfs /app/secrets:noexec,nosuid,size=100m \
myapp:latest
# Multiple tmpfs mounts
docker run -d --name app \
--tmpfs /tmp:noexec,nosuid,size=1g \
--tmpfs /var/cache:noexec,nosuid,size=500m \
myapp:latest
Container Security
Running as Non-Root User
# Dockerfile example
FROM alpine:latest
# Create user and group
RUN addgroup -g 1001 appgroup && \
adduser -D -u 1001 -G appgroup appuser
# Switch to non-root user
USER appuser
# Application files owned by appuser
COPY --chown=appuser:appgroup . /app
WORKDIR /app
# Override user at runtime
docker run -u 1001:1001 myapp:latest
# Run as specific user with home directory
docker run -u $(id -u):$(id -g) -v $HOME:/home/user myapp:latest
Security Options
# Run with security profiles
docker run --security-opt apparmor=docker-default myapp
docker run --security-opt seccomp=chrome.json myapp
# Disable privileged escalation
docker run --security-opt no-new-privileges myapp
# Drop capabilities
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
# Run with read-only root filesystem
docker run --read-only --tmpfs /tmp myapp
Resource Limits and Constraints
# Memory limits
docker run -m 512m myapp # 512 MB limit
docker run --memory=1g myapp # 1 GB limit
docker run --memory=1g --memory-swap=2g myapp # 1GB memory + 1GB swap
# CPU limits
docker run --cpus="1.5" myapp # 1.5 CPU cores
docker run --cpu-shares=512 myapp # Relative CPU weight
docker run --cpuset-cpus="0,1" myapp # Specific CPU cores
# I/O limits
docker run --device-read-bps /dev/sda:1mb myapp
docker run --device-write-bps /dev/sda:1mb myapp
# Process limits
docker run --pids-limit=100 myapp # Max 100 processes
# Ulimits
docker run --ulimit nofile=1024:1024 myapp # File descriptor limit
Production Deployment Strategies
Health Checks
# Dockerfile health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# Runtime health check
docker run -d --name web \
--health-cmd="curl -f http://localhost || exit 1" \
--health-interval=30s \
--health-timeout=3s \
--health-retries=3 \
nginx
# Check health status
docker inspect --format='{{.State.Health.Status}}' web
Restart Policies
# Always restart unless manually stopped
docker run -d --restart=unless-stopped nginx
# Restart on failure only
docker run -d --restart=on-failure:3 nginx
# Always restart
docker run -d --restart=always nginx
# Update restart policy of running container
docker update --restart=unless-stopped mycontainer
Logging Configuration
# JSON file logging with rotation
docker run -d --name app \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
myapp
# Syslog logging
docker run -d --name app \
--log-driver syslog \
--log-opt syslog-address=tcp://192.168.1.100:514 \
myapp
# Disable logging
docker run -d --name app --log-driver none myapp
# View logs with timestamps
docker logs -t app
# Follow logs in real-time
docker logs -f app
# View last N lines
docker logs --tail 50 app
Multi-Container Applications
Docker Compose Production Setup
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
- web_data:/var/www/html
depends_on:
- app
restart: unless-stopped
networks:
- frontend
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M
app:
image: myapp:latest
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://user:pass@db:5432/mydb
volumes:
- app_data:/app/data
depends_on:
- db
- redis
restart: unless-stopped
networks:
- frontend
- backend
deploy:
replicas: 3
resources:
limits:
memory: 1G
cpus: '1.0'
reservations:
memory: 512M
cpus: '0.5'
db:
image: postgres:13-alpine
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=user
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- backend
restart: unless-stopped
secrets:
- db_password
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 1G
redis:
image: redis:6-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
networks:
- backend
restart: unless-stopped
volumes:
web_data:
app_data:
postgres_data:
redis_data:
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true
secrets:
db_password:
file: ./secrets/db_password.txt
Service Discovery and Load Balancing
# docker-compose.yml with load balancer
version: '3.8'
services:
traefik:
image: traefik:v2.9
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- traefik
app:
image: myapp:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`app.example.com`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls=true"
- "traefik.http.services.app.loadbalancer.server.port=3000"
deploy:
replicas: 3
networks:
- traefik
networks:
traefik:
external: true
Container Monitoring and Debugging
Resource Monitoring
# Real-time container stats
docker stats
# Container stats in JSON format
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
# Export container filesystem as tar
docker export mycontainer > container-backup.tar
# Import container from tar
docker import container-backup.tar myimage:latest
Debugging Techniques
# Debug network connectivity
docker run --rm --network container:myapp nicolaka/netshoot
# Debug with nsenter (access container namespaces)
docker inspect myapp | grep Pid
sudo nsenter -t PID -n -p
# Copy files from/to container
docker cp myapp:/etc/nginx/nginx.conf ./
docker cp ./new-config.conf myapp:/etc/nginx/
# Create debug container with same environment
docker run -it --rm \
--network container:myapp \
--pid container:myapp \
--volumes-from myapp \
busybox sh
Log Analysis
# Search logs for patterns
docker logs myapp 2>&1 | grep ERROR
# Export logs to file
docker logs myapp > app.log 2>&1
# Real-time log filtering
docker logs -f myapp | grep -E "(ERROR|WARN)"
# Log analysis with timestamps
docker logs --since="2024-01-01T00:00:00" --until="2024-01-02T00:00:00" myapp
Performance Optimization
Image Optimization
# Multi-stage build for smaller images
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:16-alpine AS production
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]
Container Performance Tuning
# Optimize container startup
docker run -d --name app \
--memory="1g" \
--cpus="2.0" \
--oom-kill-disable=false \
--memory-swappiness=0 \
myapp:latest
# Use init process for proper signal handling
docker run -d --init myapp:latest
# Optimize I/O performance
docker run -d --name app \
--storage-opt size=20G \
--device-read-iops /dev/sda:1000 \
--device-write-iops /dev/sda:1000 \
myapp:latest
Backup and Migration
Container State Backup
# Create container snapshot
docker commit myapp myapp:backup-$(date +%Y%m%d)
# Export container as tar
docker save myapp:latest > myapp-image.tar
# Import image from tar
docker load < myapp-image.tar
# Backup all volumes
for volume in $(docker volume ls -q); do
docker run --rm \
-v $volume:/data \
-v $(pwd):/backup \
alpine tar czf /backup/$volume.tar.gz /data
done
Container Migration
# Migration script
#!/bin/bash
CONTAINER_NAME="myapp"
BACKUP_DIR="/backup"
# Create backup
docker commit $CONTAINER_NAME $CONTAINER_NAME:migration
docker save $CONTAINER_NAME:migration > $BACKUP_DIR/$CONTAINER_NAME.tar
# Copy volumes
docker run --rm \
-v myapp_data:/source \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/myapp_data.tar.gz /source
# On target host
docker load < myapp.tar
docker volume create myapp_data
docker run --rm \
-v myapp_data:/target \
-v /backup:/backup \
alpine tar xzf /backup/myapp_data.tar.gz -C /target --strip 1
Related Topics
Topics
Add topics here.