Skip to content
Latchkey

How to Run a Blue-Green Deployment From CI/CD

Blue-green keeps two identical environments and cuts traffic over only after the idle one passes health checks.

Deploy the new version to the idle color, wait for it to pass a health check, then flip the router (Service selector, load balancer target, or DNS) so all traffic lands on the new color. The old color stays warm for an immediate switchback.

How it works

You run blue and green side by side. One color serves production; the other is idle. CI deploys to the idle color, gates on a health probe, then repoints the router. Because both colors coexist, rollback is a second traffic swap, not a redeploy.

Deploy to the idle color and wait for readiness

.github/workflows/ci.yml
deploy-green:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - run: kubectl set image deployment/app-green app=myapp:${{ github.sha }}
    - name: Wait for green to become healthy
      run: kubectl rollout status deployment/app-green --timeout=120s
    - name: Gate on external health check
      run: |
        for i in $(seq 1 30); do
          if curl -fsS https://green.internal/healthz; then exit 0; fi
          sleep 5
        done
        echo "green failed health check"; exit 1

Swap traffic by repointing the Service selector

Terminal
# The Service selects pods by the "color" label; patch it to send traffic to green.
kubectl patch service app -p '{"spec":{"selector":{"app":"myapp","color":"green"}}}'

Roll back instantly

Because blue is still running the previous version, rollback is one command: patch the selector back to color: blue. No image pull, no rebuild. Keep the old color for at least one full deploy cycle before recycling it.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →