(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisbon

How to create a Blue/Green Deploy on Kubernetes with GitHub Actions

João Barros 05 de August de 2026 4 min read

This tutorial explains how to create a Blue/Green deploy on Kubernetes with GitHub Actions — a useful strategy to reduce downtime, validate new versions in production and allow fast rollback. You will see why the Blue/Green pattern is practical and a simple example to implement with manifests and a CI/CD workflow.

Prerequisites

  • GitHub account with a repository and GitHub Actions enabled
  • Accessible Kubernetes cluster (minikube, kind or AKS) and kubectl configured
  • Public or hosted Docker image (e.g.: myrepo/myapp:latest)
  • Basic familiarity with Kubernetes Deployments and Services

Step 1: Understand the Blue/Green pattern

Blue/Green means having two concurrent versions of the application: "blue" (current) and "green" (new). Traffic is switched by changing the Service selector or updating an ingress. This allows testing the green version in production without removing the blue and to roll back quickly.

Step 2: Structure the Kubernetes manifests

We will create two Deployments (app-blue and app-green) and a Service that points to a common label (app: myapp) but whose selector decides which version receives traffic. In the example the Service uses the label track: blue or track: green.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-blue
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      track: blue
  template:
    metadata:
      labels:
        app: myapp
        track: blue
    spec:
      containers:
      - name: app
        image: myrepo/myapp:stable
        ports:
        - containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-green
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      track: green
  template:
    metadata:
      labels:
        app: myapp
        track: green
    spec:
      containers:
      - name: app
        image: myrepo/myapp:canary
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: myapp
    track: blue

Step 3: Test locally on the cluster

Apply the manifests and confirm that the Service points to the blue deployment. Validate using kubectl and, if using minikube, access the service to view the application page.

# apply manifests
kubectl apply -f k8s/blue-green.yaml
# view pods and service
kubectl get deployments,pods,svc -l app=myapp
# test endpoint (minikube example)
minikube service myapp-service --url

Step 4: Create a GitHub Actions workflow for controlled deploy

The workflow builds the image, pushes it and updates the green Deployment. Then it runs a step to switch the Service from blue to green. Separating steps allows validating the version before the cutover.

name: CI CD BlueGreen
on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v4

    - name: Build and push image
      run: |
        IMAGE=myrepo/myapp:${{ github.sha }}
        docker build -t $IMAGE .
        echo "$IMAGE"
        docker push $IMAGE
      env:
        DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }}
        DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }}

    - name: Update green Deployment image
      run: |
        kubectl set image deployment/app-green app=$IMAGE --record
      env:
        KUBECONFIG: ${{ secrets.KUBECONFIG }}

    - name: Smoke tests on green
      run: |
        # Simple example: check pods are ready
        kubectl rollout status deployment/app-green --timeout=60s
        kubectl get pods -l track=green
      env:
        KUBECONFIG: ${{ secrets.KUBECONFIG }}

    - name: Switch Service to green (cutover)
      if: success()
      run: |
        kubectl patch service myapp-service -p '{"spec":{"selector":{"app":"myapp","track":"green"}}}'
      env:
        KUBECONFIG: ${{ secrets.KUBECONFIG }}

Step 5: Rollback and cleanup strategies

If something goes wrong after the cutover, point the Service back to track: blue. You can automate rollback if the smoke tests fail or use monitoring to detect issues. After stable, you can scale down the blue deployment or remove it.

# manual rollback (point back to blue)
kubectl patch service myapp-service -p '{"spec":{"selector":{"app":"myapp","track":"blue"}}}'
# remove the old version once confirmed
kubectl delete deployment app-blue

Verify the result

Confirm the Service serves the new version: make a request to the endpoint and validate headers, version or content. Use kubectl get svc and kubectl get pods -l track=green to verify traffic is on green. Monitor logs for errors and validate metrics.

Conclusion

Implementing Blue/Green deploy on Kubernetes with GitHub Actions reduces risk and simplifies rollback. Next steps: add health checks, automate performance verification and integrate monitoring (Prometheus/Alertmanager). Tip: start with minikube or kind to experiment before applying in production — what is the next service you want to launch with Blue/Green?