iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Deploy

Deployment strategy choice is risk management: how quickly can you ship, and how cheaply can you revert? The classic options are recreate (downtime), rolling, blue/green, and canary. Pick one, learn its failure modes, and commit to instrumentation so the metric that triggers rollback is automatic, not human.

GitHub Actions canary deploy with metric-based rollback

EXAMPLE
# .github/workflows/canary-deploy.yml
name: canary-deploy
on:
  push:
    branches: [main]

permissions:
  id-token: write
  contents: read

env:
  AWS_REGION: ap-southeast-2
  CLUSTER: shop-prod
  SERVICE: api

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    outputs:
      image: ${{ steps.meta.outputs.image }}
    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v4
        with: { role-to-assume: ${{ secrets.DEPLOY_ROLE_ARN }}, aws-region: ${{ env.AWS_REGION }} }
      - uses: aws-actions/amazon-ecr-login@v2
      - id: meta
        run: echo "image=${{ secrets.ECR_REPO }}:${{ github.sha }}" >> "$GITHUB_OUTPUT"
      - run: docker build -t ${{ steps.meta.outputs.image }} . && docker push ${{ steps.meta.outputs.image }}

  canary:
    needs: build-and-push
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v4
        with: { role-to-assume: ${{ secrets.DEPLOY_ROLE_ARN }}, aws-region: ${{ env.AWS_REGION }} }

      # 1) Deploy 10% canary
      - name: Start 10% canary
        run: scripts/deploy.sh canary --image ${{ needs.build-and-push.outputs.image }} --pct 10

      # 2) Watch error rate and p95 latency for 5 minutes
      - name: Bake & monitor
        id: monitor
        run: scripts/check-health.sh --window 5m --error-rate-max 1 --p95-ms-max 800

      # 3) Promote in steps if healthy
      - name: Promote 25%
        if: steps.monitor.outcome == 'success'
        run: scripts/deploy.sh canary --pct 25 && scripts/check-health.sh --window 5m

      - name: Promote 50%
        if: steps.monitor.outcome == 'success'
        run: scripts/deploy.sh canary --pct 50 && scripts/check-health.sh --window 5m

      - name: Promote 100%
        if: steps.monitor.outcome == 'success'
        run: scripts/deploy.sh promote

      # 4) Automatic rollback on failure
      - name: Roll back
        if: failure()
        run: scripts/deploy.sh rollback && scripts/notify.sh slack --channel deploys --status failure

# scripts/check-health.sh (sketch)
# Query CloudWatch / Prometheus for the canary task set's
# 5xx rate, p95 latency, business KPI (orders/min). Exit non-zero
# if any threshold breaches. Each promotion step calls this.

# Alternative strategies, picked by risk:
# - rolling:    safe + cheap default for stateless services
# - blue/green: full duplicate stack, instant rollback via traffic swap
# - canary:     least blast radius, requires good metrics + automated checks
# - recreate:   acceptable for batch / nightly only — no production traffic

Why it matters

The strategy is only as good as the metric. A canary that promotes after \"the job didnt fail\" is theatre — a canary that promotes only when error rate, latency, and a business KPI all stay within bounds is real risk control. Wire the metrics first; the workflow second.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
- name: Deploy
  run: |
      ssh deploy@${{ secrets.HOST }} 'docker pull me/app:${{ github.sha }} && \
          docker run -d --restart=always --name app me/app:${{ github.sha }}'
Try it Yourself »

Discussion

Loading…