Blue-green deployment runs two identical production environments — only one live at a time — letting you switch traffic instantly between them, enabling zero-downtime releases and instant rollback if something goes wrong.
The Core Concept
- Blue environment is currently live, serving production traffic
- Green environment is idle, where you deploy and test the new version
- Once verified, traffic switches from blue to green
- Blue becomes the new idle environment, ready for the next deployment cycle
Prerequisites
- A VPS with sufficient resources to run two instances of your application simultaneously
- Nginx as a reverse proxy in front of both environments
Step 1 — Run Two Instances of Your Application
Using Docker Compose, run blue on one port and green on another:
services:
app-blue:
image: myapp:current
ports:
- "3001:3000"
app-green:
image: myapp:next
ports:
- "3002:3000"
Step 2 — Configure Nginx to Route to the Active Environment
upstream backend {
server 127.0.0.1:3001; # currently blue is active
}
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://backend;
}
}
Step 3 — Deploy the New Version to the Idle Environment
docker compose pull app-green
docker compose up -d app-green
Step 4 — Test the Idle Environment Directly
curl http://127.0.0.1:3002/health
Run your full test suite or manual verification against the green environment before it receives any real traffic.
Step 5 — Switch Traffic
sudo nano /etc/nginx/sites-available/myapp
upstream backend {
server 127.0.0.1:3002; # now green is active
}
sudo nginx -t && sudo systemctl reload nginx
reload (not restart) applies the change without dropping any in-flight connections.
Step 6 — Monitor After the Switch
Watch error rates and logs closely for a period after switching — if issues appear, rolling back is simply switching the upstream back to blue.
Step 7 — Rolling Back (If Needed)
upstream backend {
server 127.0.0.1:3001; # revert to blue
}
sudo nginx -t && sudo systemctl reload nginx
This is the core benefit of blue-green: rollback is a near-instant configuration switch, not a redeploy.
Step 8 — Prepare Blue for the Next Cycle
Once green is confirmed stable, blue becomes the new idle environment, ready to receive the next deployment.
Database Migration Considerations
Blue-green deployment becomes more complex with database schema changes, since both environments typically share the same database. Design migrations to be backward-compatible during the transition window (additive changes deployed ahead of the code that requires them, destructive changes deployed only after the old code is fully retired).
Automating the Switch
sudo nano /usr/local/bin/switch-to-green.sh
#!/bin/bash
sed -i 's/3001/3002/' /etc/nginx/sites-available/myapp
nginx -t && systemctl reload nginx
echo "Switched to green at $(date)"
Common Errors
Switch causes a brief connection drop — confirm you used reload, not restart, since restart briefly stops and starts the entire Nginx process.
Best Practices
- Always fully test the idle environment before switching traffic to it
- Design database migrations to be backward-compatible across the transition window
- Monitor closely immediately after every switch
Continue Reading
- Canary Deployments: Gradually Rolling Out Changes
- How to Roll Back a Bad Deployment Quickly
- How to Set Up Basic Load Balancing with Nginx
Browse more articles in DevOps & CI/CD.
