How to Do a Blue-Green Deploy With GitHub Actions
Deploy the new version to the idle color, verify it, then flip the router so all traffic moves at once with an instant rollback path.
Blue-green keeps two environments. Deploy to the inactive one, smoke test it, then switch the alias or load balancer target. The old color stays warm so rollback is just another switch.
Steps
- Determine the idle color (the one not serving traffic).
- Deploy the new build to that color and run smoke tests against it.
- Switch the load balancer/alias to the new color.
- Keep the old color until you are confident, then scale it down.
Workflow
.github/workflows/deploy.yml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- id: target
run: |
ACTIVE=$(./scripts/active-color.sh) # e.g. blue
echo "idle=$([ "$ACTIVE" = blue ] && echo green || echo blue)" >> "$GITHUB_OUTPUT"
- run: ./scripts/deploy.sh --color ${{ steps.target.outputs.idle }} --sha ${{ github.sha }}
- run: ./scripts/smoke.sh --color ${{ steps.target.outputs.idle }}
- run: ./scripts/switch-traffic.sh --to ${{ steps.target.outputs.idle }}Common pitfalls
- Switching traffic before smoke tests pass defeats the purpose; gate the switch on the test step.
- Sharing one database across both colors means a breaking migration affects the live color too; use backward-compatible migrations.
- Forgetting to drain the old color wastes capacity and cost while it idles.
Related guides
How to Do a Canary Deploy With GitHub ActionsRoll out a canary deployment from GitHub Actions by shifting a small traffic percentage to the new version, w…
How to Roll Back a Deployment With GitHub ActionsRoll back a bad deploy from GitHub Actions with a workflow_dispatch input that redeploys a previous version o…