Blue-Green Deployment in Production with Kubernetes and Nginx
When I choose blue-green
Blue-green keeps two complete application versions:
BLUE = current production
GREEN = new releaseTraffic initially goes to blue.
Green is deployed and validated independently.
Then routing switches.
Users
|
v
Router / Service
|
+--> BLUE 100%
|
`--> GREEN 0%
after approval:
Users
|
v
Router / Service
|
+--> BLUE 0%
|
`--> GREEN 100%I use this for releases where rollback speed matters more than temporary duplicate capacity cost.
Kubernetes label approach
Blue:
apiVersion: apps/v1
kind: Deployment
metadata:
name: booking-blue
spec:
replicas: 6
selector:
matchLabels:
app: booking
version: blue
template:
metadata:
labels:
app: booking
version: blueGreen:
apiVersion: apps/v1
kind: Deployment
metadata:
name: booking-green
spec:
replicas: 6
selector:
matchLabels:
app: booking
version: green
template:
metadata:
labels:
app: booking
version: greenProduction Service:
apiVersion: v1
kind: Service
metadata:
name: booking-service
spec:
selector:
app: booking
version: blue
ports:
- port: 80
targetPort: 8080After validation:
kubectl patch service booking-service \
-p '{"spec":{"selector":{"app":"booking","version":"green"}}}'Rollback is the reverse selector switch.
Nginx switch
upstream booking_blue {
server booking-blue:8080;
}
upstream booking_green {
server booking-green:8080;
}
server {
location / {
proxy_pass http://booking_green;
}
}I reload Nginx only after config validation:
nginx -t && nginx -s reloadPre-switch validation
Green can be exposed through an internal route:
https://green.internal.exampleI run:
- health checks;
- synthetic login;
- search;
- create/cancel low-risk test transaction;
- dependency connectivity;
- telemetry validation;
- version endpoint check.
Shared database risk
Blue and green often share the same DB.
Therefore the database must support both versions.
If green writes a new value that blue cannot understand, rollback may fail even though routing is easy.
Blue-green does not solve database compatibility.
Sessions
If sessions are stored in local memory, switching environments logs users out or loses workflow state.
I prefer:
stateless signed session
or
shared external session storefor switchable environments.
Background workers
This is a common overlooked problem.
If blue and green both run Kafka consumers or schedulers, deploying green at full replica count can process production work twice.
I separate:
web/API traffic switching
background job activation
consumer group/version activationGreen workers may start disabled or use isolated test topics until cutover.
Rollback window
I keep blue available for a defined period:
30 minutes
2 hours
one business cycledepending on risk/cost.
After confidence, blue is scaled down and eventually removed.
Production checklist
- Duplicate capacity available.
- Database compatible with both.
- Session state externalized.
- Background workers controlled.
- Internal green test route.
- Automated smoke suite.
- Routing switch scripted.
- Routing rollback scripted.
- Monitor version-specific metrics.
- Define blue retention window.
FAQ
Blue-green vs canary?
Blue-green switches environments quickly. Canary gradually shifts user traffic and provides earlier production evidence.
Is rollback instant?
Routing rollback can be fast, but only if schema and produced data remain compatible.
Does blue-green double cost?
Temporarily, often yes. That is the price for fast switch/rollback.
Related architecture guides
- [Production Deployment Patterns I Have Used](/articles/production-deployment-patterns-blue-green-canary-rolling)
- [Rolling Deployment](/articles/rolling-deployment-kubernetes-production)
-
Architect's final take
I use blue-green when I want to validate a complete release environment before the public switch and when the temporary capacity cost is justified by rollback speed.
Your feedback helps prioritize deeper technical content.






