Docker Expert
Overview
Advanced expertise in Docker — from writing efficient Dockerfiles and Docker Compose configurations to container networking, security hardening, multi-stage builds, and production deployment patterns.
1. Dockerfile Best Practices
Optimized Node.js Example
# ---- Build stage ----
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# ---- Production stage ----
FROM node:20-alpine AS runner
WORKDIR /app
# Non-root user for security
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
COPY --from=builder /app/node_modules ./node_modules
COPY --chown=appuser:appgroup . .
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "server.js"]
Optimized Next.js / React App
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -S nodejs && adduser -S nextjs -G nodejs
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]
Python (FastAPI) Example
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
RUN useradd -r -s /bin/false appuser
COPY --from=builder /root/.local /home/appuser/.local
COPY --chown=appuser . .
USER appuser
ENV PATH=/home/appuser/.local/bin:$PATH
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
2. Layer Caching Optimization
- Order instructions from least to most frequently changing
COPY package*.json ./→RUN npm ci→COPY . .- Use
.dockerignoreaggressively:node_modules/ .git/ .env* dist/ build/ **/*.log .DS_Store README.md - Use
--mount=type=cache(BuildKit) for package manager caches:RUN --mount=type=cache,target=/root/.npm npm ci
3. Docker Compose
Full-stack App Example
# docker-compose.yml
version: '3.9'
services:
app:
build:
context: .
target: runner
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
- REDIS_URL=redis://redis:6379
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- app-network
restart: unless-stopped
db:
image: postgres:16-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
command: redis-server --appendonly yes
networks:
- app-network
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- app
networks:
- app-network
volumes:
postgres_data:
redis_data:
networks:
app-network:
driver: bridge
Override for Development
# docker-compose.override.yml (auto-loaded in dev)
services:
app:
build:
target: builder
volumes:
- .:/app
- /app/node_modules
command: npm run dev
environment:
- NODE_ENV=development
Common Commands
docker compose up -d # start detached
docker compose up --build # rebuild images
docker compose down # stop & remove containers
docker compose down -v # also remove volumes
docker compose logs -f app # follow logs
docker compose exec app sh # shell into container
docker compose ps # list running services
docker compose restart app # restart single service
docker compose pull # pull latest images
4. Networking
- bridge (default): isolated network, containers communicate by service name
- host: container shares host network stack (Linux only)
- none: no networking
- Custom bridge networks enable DNS resolution by container/service name
--network hostfor performance-sensitive scenarios
docker network create my-net
docker run --network my-net --name api my-api-image
docker run --network my-net --name frontend my-frontend-image
# frontend can reach api at http://api:3000
5. Volumes & Storage
# Named volume (managed by Docker, persists)
docker run -v postgres_data:/var/lib/postgresql/data postgres
# Bind mount (host directory → container)
docker run -v $(pwd)/src:/app/src my-image
# Read-only bind mount
docker run -v $(pwd)/config:/app/config:ro my-image
# tmpfs mount (in-memory, not persisted)
docker run --tmpfs /tmp my-image
# List & inspect
docker volume ls
docker volume inspect postgres_data
docker volume prune # remove unused volumes
6. Image Management
# Build
docker build -t myapp:1.0.0 .
docker build -t myapp:latest --target builder .
docker build --build-arg NODE_ENV=production -t myapp .
DOCKER_BUILDKIT=1 docker build . # enable BuildKit
# Tag & Push
docker tag myapp:latest ghcr.io/user/myapp:latest
docker push ghcr.io/user/myapp:latest
# Inspect & Debug
docker images
docker image inspect myapp:latest
docker history myapp:latest
docker image prune -a # remove unused images
# Multi-platform builds (BuildKit required)
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 -t user/app:latest --push .
7. Container Security
- Never run as root: add
RUN useraddandUSERdirective - Minimal base images:
alpine,distroless,scratch - No secrets in layers: use
--secretflag or runtime env varsRUN --mount=type=secret,id=npm_token npm install - Read-only filesystem:
docker run --read-only - Drop capabilities:
--cap-drop ALL --cap-add NET_BIND_SERVICE - Scan images:
docker scout cves myapp:latestortrivy image myapp - Signed images: Docker Content Trust (
DOCKER_CONTENT_TRUST=1) - Pin base image digests for reproducibility:
FROM node:20-alpine@sha256:abc123...
8. Health Checks
# In Dockerfile
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
# Or in docker-compose.yml
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
9. BuildKit Features
# Enable BuildKit
export DOCKER_BUILDKIT=1
# Build secrets (not stored in image layers)
docker build --secret id=mysecret,src=./secret.txt .
# SSH forwarding for private repos
docker build --ssh default .
# In Dockerfile:
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret
RUN --mount=type=ssh git clone git@github.com:private/repo.git
10. Production Deployment Patterns
Container Registry
# GitHub Container Registry
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
docker push ghcr.io/owner/image:tag
# AWS ECR
aws ecr get-login-password | docker login --username AWS \
--password-stdin 123456.dkr.ecr.us-east-1.amazonaws.com
Resource Limits
# docker-compose.yml
services:
app:
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
memory: 256M
Logging
docker run --log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
my-image
11. Debugging Containers
# Shell into running container
docker exec -it container_name sh
# Shell into stopped container (debug)
docker run -it --entrypoint sh my-image
# Copy files from container
docker cp container_name:/app/logs ./local-logs
# View resource usage
docker stats
# Inspect container config
docker inspect container_name | jq '.[0].Config'
# View logs
docker logs -f --tail=100 container_name
12. docker-compose vs docker compose
docker compose(v2, plugin) — current standard, built into Docker Desktopdocker-compose(v1, standalone) — legacy Python binary, deprecated- Use
docker composefor all new projects
Core Competency Summary
- Write efficient, secure multi-stage Dockerfiles
- Configure Docker Compose for full-stack development and production
- Implement container networking, volumes, and health checks
- Harden containers: non-root users, minimal images, secret handling
- Build and push multi-platform images with BuildKit
- Debug and monitor running containers
- Deploy containerized apps to cloud registries and orchestrators