Docker Compose Tip #18: Graceful shutdown with stop_grace_period

Give your containers time to clean up. Configure grace periods to ensure database connections close, transactions complete, and data saves properly. The problem By default, Docker gives containers 10 seconds to stop before forcefully killing them: services: app: image: myapp:latest # Container gets SIGTERM, then SIGKILL after 10s This can interrupt long-running operations and corrupt data. The solution Use stop_grace_period to extend shutdown time: services: worker: image: myworker:latest stop_grace_period: 2m # 2 minutes to finish current job stop_signal: SIGTERM # Signal to send first (default) Real-world examples Different services need different grace periods: ...

January 28, 2026 · 2 min · 358 words · Guillaume Lours

Docker Compose Tip #17: YAML anchors to reduce duplication

Stop copy-pasting the same configuration. YAML anchors let you define once and reuse everywhere in your Compose files. The basics Define an anchor with & and reference it with *: services: web: &default-app image: myapp:latest environment: NODE_ENV: production LOG_LEVEL: info networks: - app-network worker: <<: *default-app # Inherit all settings from web command: npm run worker The worker service inherits everything from web, then overrides the command. ...

January 27, 2026 · 2 min · 297 words · Guillaume Lours

Docker Compose Tip #16: Setting resource limits with deploy.resources

Prevent containers from consuming all available resources. Set CPU and memory limits to ensure stable multi-service deployments. The basics Resource limits protect your system from runaway containers: services: api: image: node:20 deploy: resources: limits: cpus: '0.5' # Half a CPU core memory: 512M # 512 megabytes reservations: cpus: '0.25' # Minimum guaranteed memory: 256M The container can use up to 512MB memory and 50% of one CPU core. ...

January 26, 2026 · 2 min · 318 words · Guillaume Lours

Docker Compose Tip #15: Blue-green deployments with Traefik

Deploy with zero downtime using Traefik’s dynamic routing. Switch traffic between blue and green deployments by updating environment variables, with automatic health checks. The setup Traefik automatically discovers services and routes traffic based on labels: # compose.yml services: traefik: image: traefik:v3.0 command: - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" ports: - "80:80" - "8080:8080" # Traefik dashboard volumes: - /var/run/docker.sock:/var/run/docker.sock:ro networks: - web app-blue: image: myapp:${BLUE_VERSION:-v1.0} labels: - "traefik.enable=${BLUE_ENABLED:-true}" - "traefik.http.routers.app-blue.rule=Host(`app.localhost`)" - "traefik.http.routers.app-blue.priority=1" - "traefik.http.services.app-blue.loadbalancer.server.port=3000" networks: - web environment: VERSION: blue app-green: image: myapp:${GREEN_VERSION:-v2.0} labels: - "traefik.enable=${GREEN_ENABLED:-false}" # Start disabled - "traefik.http.routers.app-green.rule=Host(`app.localhost`)" - "traefik.http.routers.app-green.priority=2" # Higher priority when enabled - "traefik.http.services.app-green.loadbalancer.server.port=3000" networks: - web environment: VERSION: green networks: web: driver: bridge Deployment workflow Switch traffic by recreating containers with updated labels: ...

January 23, 2026 · 2 min · 351 words · Guillaume Lours

Docker Compose Tip #14: Running containers as non-root users

Running containers as root is a security risk. Configure your services to use non-root users for defense in depth. The problem By default, many containers run as root: services: app: image: nginx # Runs as root user (uid 0) - security risk! If compromised, attackers have root privileges inside the container. The solution Set the user in compose.yml: services: app: image: node:20 user: "1000:1000" # Run as uid:gid 1000 working_dir: /app volumes: - ./app:/app Or use the image’s built-in user: ...

January 22, 2026 · 2 min · 363 words · Guillaume Lours