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

Docker Compose Tip #13: Using external networks to connect multiple projects

Need your frontend project to talk to a backend in another Compose project? External networks let you connect containers across different stacks. The problem Two separate Compose projects need to communicate: frontend/compose.yml - React app backend/compose.yml - API service By default, each creates its own isolated network. The solution Create a shared external network: # Create the network once docker network create shared-network Then reference it in both projects: backend/compose.yml: ...

January 21, 2026 · 2 min · 308 words · Guillaume Lours

Docker Compose Tip #12: Using target to specify build stages

One Dockerfile, multiple environments. Use target to build only the stage you need - faster builds, smaller images, cleaner separation. The basics Multi-stage Dockerfile: # Development stage FROM node:20-alpine AS development WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["npm", "run", "dev"] # Production stage FROM node:20-alpine AS production WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . RUN npm run build CMD ["npm", "start"] Target specific stages in compose.yml: ...

January 20, 2026 · 2 min · 313 words · Guillaume Lours

Docker Compose Tip #11: Mastering docker compose up --watch for hot reload

Stop manually restarting containers when code changes. Docker Compose Watch automatically syncs files and reloads services - zero interruption development. The basics Enable watch mode with: docker compose up --watch # If you don't want mixed logs, you can run it in a dedicated process, you need to have your stack started on its own process docker compose watch Then configure watching in your compose.yml: services: web: image: node:20 command: npm start develop: watch: - path: ./src target: /app/src action: sync - path: package.json action: rebuild Files in ./src sync instantly. Changes to package.json trigger a rebuild. ...

January 19, 2026 · 2 min · 365 words · Guillaume Lours