How to create a Blue/Green Deploy on Kubernetes with GitHub Actions
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?