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 #8: Healthchecks with Docker Hardened Images

Docker Hardened Images (DHI) maximize security by removing shells and package managers. But how do you add healthchecks? Use a secure sidecar with shared network namespace. The problem Your hardened Node.js application: services: app: image: dhi.io/node:25-debian13-sfw-ent-dev healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] # FAILS: No curl in hardened image! The solution: Network namespace sidecar Use a hardened curl image that shares the app’s network: services: app: image: dhi.io/node:25-debian13-sfw-ent-dev ports: - "3000:3000" environment: NODE_ENV: production app-health: image: dhi.io/curl:8-debian13-dev entrypoint: ["sleep", "infinity"] network_mode: "service:app" # Shares app's network namespace! healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 3s retries: 3 start_period: 10s The network_mode: "service:app" allows the sidecar to access localhost:3000 directly - they share the same network stack! ...

January 14, 2026 · 3 min · 478 words · Guillaume Lours