Blue-green deployment setup

Learn to set up blue-green deployments: switch traffic between two identical environments for low-risk releases. This tutorial covers the core concept, step-by-step walkthrough, and troubleshooting tips — perfect for CI/CD foundations.

Focus: set up a blue-green deployment strategy

Sponsored

You’ve automated your builds and tests, but every release still feels like a high-wire act: one bad deploy, and your users are staring at a 502 while you scramble to roll back. The fix isn’t more caution — it’s a blue-green deployment strategy, a pattern that lets you switch traffic between two identical environments so releases become a routine, reversible flip. Here’s how to set one up and why it’s a cornerstone of modern CI/CD.

The problem this lesson solves

Traditional rolling deployments update instances one by one, so at any moment your cluster hosts a mix of old and new code. That’s fine for internal tools, but it creates a nightmare for user-facing services: version skew, database migrations that run against half-updated code, and a painful rollback that means redeploying the old version.

A blue-green deployment eliminates that mixing by keeping two production environments: blue (the current, stable version) and green (the new release). You deploy to green, test it in production-like conditions, then flip the router or load balancer to send all traffic to green. If something breaks, you flip back — no code redeploy, no downtime, no half-states.

The pain is real: without blue-green, rollbacks take minutes (or hours) and require a full redeploy. With blue-green, rollback is a single router change that takes seconds. That speed is what makes set up a blue-green deployment strategy a skill worth mastering.

Why it matters now: As your CI/CD pipeline matures, release frequency goes up. Blue-green deployments let you ship daily (or hourly) without turning every deploy into an incident.

Core concept / mental model

Think of a light switch in a dark room with two identical light bulbs. One bulb (blue) is lit — that’s your current live traffic. The other (green) is off — it’s the new code you’ve prepared. You wire up the new bulb, test it in the dark, then flip the switch. If the room catches fire, you flip back. That’s blue-green: two identical environments, one active at a time, a switch between them.

Defining terms

  • Blue environment: The currently live version, receiving 100% of production traffic.
  • Green environment: A fully provisioned, exact copy of blue, but with the new code deployed. It’s idle until you switch.
  • Router or load balancer: The traffic switch — nginx, AWS ALB, Kubernetes Service, etc. It points at blue or green.
  • Cutover: The moment you flip traffic from blue to green.
  • Rollback: Flipping back to blue after a bad cutover.

Key principles

  • Idempotence: Green must be created from the same infrastructure-as-code (Terraform, CloudFormation) as blue, so they’re identical.
  • Database challenges: The database is shared, so schema changes must be backward-compatible (expand-migrate-contract).
  • Cutover is not deployment: Deployment is to green; cutover is a traffic switch. Always separate them mentally.

When NOT to use it

  • Stateful workloads: Databases, queues, or any service with client sessions stored locally — cutting over loses state.
  • Cost-sensitive projects: Doubling infrastructure costs is hard to justify for a small hobby app.

How it works step by step

A blue-green deployment follows a repeatable sequence:

  1. Provision the green environment — Spin up an identical stack from your CI/CD pipeline or infrastructure code.
  2. Deploy the new version to green — Run your build, run tests, deploy the artifact to green.
  3. Validate green in isolation — Run smoke tests, health checks, and maybe a canary test against green’s internal URL.
  4. Switch traffic — Update the router to point at green; this is the atomic cutover. All new requests go to green.
  5. Monitor — Watch metrics, errors, and logs for a burn-in period (15–60 minutes).
  6. Keep blue for rollback — Leave blue alive. If anything breaks, flip the router back.
  7. Retire blue (optional) — After a day or two, tear down blue or reuse it for the next green.

Why the switch is atomic

In step 4, the router update is a single configuration change — either it points at blue or green. There’s no window where traffic splits, no version mixing. That atomicity is the core safety property.

Hands-on walkthrough

Let’s see blue-green in action. I’ll show two scenarios: one using a simple nginx router, and one with Kubernetes.

Scenario 1: Nginx-based blue-green

You have two directories: blue/ and green/, each containing an index.html. Below is a minimal nginx config that serves one of them, with a variable to switch.

http {
    upstream backend {
        server blue-app:8080; # or green-app:8080
    }
    server {
        listen 80;
        location / {
            proxy_pass http://backend;
        }
    }
}

To cut over, you’d edit that server line and reload nginx — but that’s manual. A better way is to use Docker Compose and a simple switch.sh:

#!/bin/bash
# switch.sh — flips traffic between blue and green
if [[ "$(cat current)" == "blue" ]]; then
    echo "green" > current
    docker compose up -d green-app
    # Update nginx config to point at green-app
    sed -i 's/server blue-app/server green-app/' nginx.conf
    docker compose exec nginx nginx -s reload
    echo "Switched to green"
else
    echo "blue" > current
    docker compose up -d blue-app
    sed -i 's/server green-app/server blue-app/' nginx.conf
    docker compose exec nginx nginx -s reload
    echo "Switched to blue"
fi

This script flips a marker file and reloads nginx. It’s the essence of the strategy — swap, reload, done.

Scenario 2: Kubernetes blue-green

Kubernetes gives you two Deployments (blue and green) and a Service that selects one via labels. Here’s the green deployment:

# green-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-green
  labels:
    app: myapp
    version: green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      version: green
  template:
    metadata:
      labels:
        app: myapp
        version: green
    spec:
      containers:
      - name: app
        image: myapp:v2.0
        ports:
        - containerPort: 8080

And the Service that acts as the router:

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: myapp
    version: blue   # change to green to switch
  ports:
  - port: 80
    targetPort: 8080

To cut over, just edit the selector:

kubectl apply -f green-deployment.yaml
# Validate green (run smoke tests against its ClusterIP)
kubectl get pods -l version=green
# Switch traffic
kubectl patch service app-service -p '{"spec":{"selector":{"version":"green"}}}'

That single kubectl patch is your atomic switch. Rollback is the same command with blue.

Pro tip: Always run smoke tests against green before the switch. In Kubernetes, you can expose green via a temporary internal service or port-forward.

Expected output

When you run the Kubernetes switch, you’ll see:

service/app-service patched

And if you kubectl get pods within seconds, you’ll see green pods receiving traffic. If you monitor logs, you’ll see new requests hitting only green.

Compare options / when to choose what

Blue-green isn’t the only release strategy. Here’s how it stacks up:

Strategy Downtime Rollback speed Cost Database risk Best for
Blue-green Zero Instant (flip) Double infra Shared DB issues APIs, web apps, services with low state
Canary Zero Moderate (scale down) Slightly higher (partial) Shared DB still risky Gradual rollout, feature flags
Rolling Zero Slow (redeploy old) Low (single set) Can be risky (mixed versions) Internal services, stateless apps
Recreate Downtime Fast (redeploy) Low Simple Batch jobs, dev environments

When to choose blue-green

  • You need instant rollback: A single command reverts to the previous version.
  • You can afford two environments: Even for a small service, doubling resources might be acceptable at low traffic.
  • You can manage database compatibility: Your migrations are backward-compatible.

Variations

  • Canary with blue-green: Route 5% of traffic to green first (using weighted load balancing), then flip completely after validation.
  • Blue-green with database blue/green: Replicate your DB and switch connections — complex but possible for zero-downtime schema changes.
  • Blue-green for serverless: Use API Gateway stage variables to switch between Lambda aliases or versions.

Troubleshooting & edge cases

Common mistakes and fixes

  • Database not compatible: Your new code works against an old schema, but cutover breaks writes. Fix: use expand-migrate-contract — add new columns first, release, then clean up. Always test migrations against a copy.
  • Green environment drifts: Green isn’t truly identical because someone hand-tweaked it. Fix: provision both environments with the same Terraform module; never manually configure.
  • Session state lost: Users get logged out after cutover because sessions are stored in memory on blue. Fix: store sessions in Redis or a database shared across environments.
  • DNS caching delays: If you flip via DNS instead of a load balancer, clients may hit the old IP for hours. Fix: always use a load balancer or service to switch; avoid DNS-level cutover.
  • The switch wasn’t atomic: You edited a config file over several seconds, and traffic hit a mixed state. Fix: use a single atomic update (e.g., Kubernetes patch, or a config management tool) and reload, not incremental edits.

Edge cases

  • Blue-green with a message queue: If green consumes from the same queue as blue, you’ll have duplicate processing. You need to pause blue consumers before cutover.
  • Multiple services: If your app spans several microservices, you need to coordinate cutovers across all of them or you’ll get version skew. Use a service mesh or feature flags to handle it.
  • Long-running requests: In-flight requests may still be handled by blue after cutover. Design your load balancer to drain connections before fully switching.

What you learned & what's next

Now you can set up a blue-green deployment strategy: you understand the mental model of two identical environments, you’ve seen the step-by-step sequence, you’ve implemented it with both nginx and Kubernetes, and you know when to prefer it over canary or rolling. You know that rollback is just a flip, and you’ve learned to dodge the common database and session pitfalls.

You’ve met both learning objectives: you can explain the core idea, and you can complete a hands-on exercise. In the next lesson in this CI/CD foundations track, you’ll learn how to automate the whole blue-green process in your CI/CD pipeline — wiring the deployment and switch into your GitHub Actions or Jenkins workflow so cuts are one-click. That’s where the real speed lives.

Practice recap

Try this: on a test cluster or Docker Compose setup, deploy a simple web app to ‘blue’, then create ‘green’ with a different version. Run a smoke test against green, then switch the service selector (or nginx upstream) to green. Verify traffic hits green, then flip back to blue — measure the time it takes. This hands-on exercise will cement the atomic switch concept.

Common mistakes

  • Not making the switch atomic — scientists update a config file in multiple steps, causing mixed traffic. Always use a single atomic update like kubectl patch or a config reload.
  • Ignoring database compatibility — your new schema breaks the old code during rollback. Follow expand-migrate-contract: add new columns first, release, then clean up.
  • Forgetting session state — users get logged out after cutover because sessions live in memory on the old environment. Store sessions in Redis or a shared DB.
  • Using DNS-based cutover — DNS caching delays mean some users hit the old IP for hours. Use a load balancer or service as the switch, not DNS.
  • Letting green and blue drift — manual tweaks make environments non-identical, breaking rollbacks. Provision both from the same Terraform module or pipeline.

Variations

  1. Canary with blue-green: route a small percentage of traffic to green first (weighted load balancer), validate, then flip 100%. Useful when you want extra safety before full cutover.
  2. Blue-green with database replication: maintain a database replica for green and switch connections atomically — complex but gives zero-downtime schema changes.
  3. Serverless blue-green: use API Gateway stage variables to switch between Lambda aliases/versions — a lightweight cloud-native take on the pattern.

Real-world use cases

  • You manage a public REST API with millions of requests; a bad deploy would take down the service. Blue-green gives instant rollback with zero downtime.
  • Your SaaS platform does weekly releases to production; you need to validate the new version in a production-like environment before switching all users, and you must keep the old version available for rollback.
  • You run a Kubernetes microservices app; you use blue-green deployments for each service to avoid version skew during upgrades, with a service mesh controlling traffic.

Key takeaways

  • Blue-green deployments use two identical environments — blue (live) and green (new) — with an atomic traffic switch between them.
  • The cutover is a single router or load-balancer change, not a redeployment; rollback is the same flip in reverse.
  • Always validate green in isolation (smoke tests, health checks) before switching traffic.
  • Database changes must be backward-compatible; use expand-migrate-contract to avoid rollback issues.
  • Keep blue alive for rollback until you’re confident in green; then retire it to save costs.
  • Blue-green is ideal when you need instant rollback, but it doubles infrastructure cost — consider canary for gradual rollout.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.