0
0
Dockerdevops~5 mins

Canary deployment pattern in Docker - Commands & Configuration

Choose your learning style9 modes available
Introduction
When you want to update your app without risking all users seeing a broken version, canary deployment helps. It sends the new version to a small group first, then gradually to everyone if all goes well.
When releasing a new feature and you want to test it with a small group of users first
When fixing a bug and you want to make sure the fix works before full rollout
When updating your app but want to reduce downtime and risk
When you want to monitor the new version's performance before full deployment
When you want to rollback quickly if the new version causes problems
Config File - docker-compose.yml
docker-compose.yml
version: '3.8'
services:
  app:
    image: my-app:stable
    ports:
      - "80:80"
  app_canary:
    image: my-app:canary
    ports:
      - "8080:80"
    deploy:
      replicas: 1
      labels:
        - "traefik.http.routers.app_canary.rule=PathPrefix(`/`) && Headers(`X-Canary`, `true`)"

This file defines two services: app runs the stable version on port 80, and app_canary runs the new canary version on port 8080.

The canary service is set to one replica to limit exposure.

Labels can be used by a reverse proxy like Traefik to route only users with a special header to the canary version.

Commands
Start both the stable and canary app versions in the background so they run simultaneously.
Terminal
docker-compose up -d
Expected OutputExpected
Creating network "default" with the default driver Creating volume "default_app_data" with default driver Creating default_app_1 ... done Creating default_app_canary_1 ... done
-d - Run containers in detached mode (in the background)
Check that both the stable and canary containers are running.
Terminal
docker ps
Expected OutputExpected
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES abc123def456 my-app:stable "/bin/sh -c 'npm start'" 10 seconds ago Up 9 seconds 0.0.0.0:80->80/tcp default_app_1 xyz789ghi012 my-app:canary "/bin/sh -c 'npm start'" 10 seconds ago Up 9 seconds 0.0.0.0:8080->80/tcp default_app_canary_1
Send a request with the special header to test the canary version directly.
Terminal
curl -H "X-Canary: true" http://localhost:8080
Expected OutputExpected
<html><body><h1>Welcome to my-app Canary Version</h1></body></html>
Send a normal request to the stable version to confirm it is still serving users.
Terminal
curl http://localhost:80
Expected OutputExpected
<html><body><h1>Welcome to my-app Stable Version</h1></body></html>
Key Concept

If you remember nothing else from this pattern, remember: deploy the new version to a small user group first, then gradually shift all traffic if it works well.

Common Mistakes
Deploying the new version directly to all users without testing.
This risks exposing all users to bugs or downtime if the new version has issues.
Use canary deployment to test with a small group before full rollout.
Not routing traffic properly to the canary version for testing.
Without directing some users to the canary, you cannot verify it works in production.
Use headers or routing rules in your proxy to send a subset of users to the canary.
Running too many replicas of the canary version initially.
This increases risk by exposing too many users to an untested version.
Start with one or very few replicas for the canary.
Summary
Use docker-compose to run stable and canary app versions side by side.
Route a small portion of traffic to the canary version using headers or proxy rules.
Test the canary version before shifting all users to it.