• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Zero-Downtime Blue-Green Deployment Pipelines for Python Applications on Google Cloud

Zero-Downtime Blue-Green Deployment Pipelines for Python Applications on Google Cloud

We can automate the blue-green deployment process using Cloud Build. This pipeline will:

  • Build the new Docker image for the Green environment.
  • Push the image to Google Container Registry (GCR) or Artifact Registry.
  • Update the Green Deployment with the new image.
  • Perform health checks on the Green environment.
  • Update the Ingress to point to the Green Service.
  • (Optional) Scale down the Blue deployment or prepare it for the next cycle.

Here’s a sample cloudbuild.yaml:

steps:
# 1. Build the new Docker image for the Green environment
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/my-python-app:$COMMIT_SHA', '.']
  id: 'Build Image'

# 2. Push the image to GCR
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'gcr.io/$PROJECT_ID/my-python-app:$COMMIT_SHA']
  id: 'Push Image'

# 3. Update the Green Deployment with the new image
# This step requires kubectl configured for your GKE cluster.
# We'll use kustomize or sed to update the image tag in the deployment manifest.
# For simplicity, let's assume we have a deployment-green.yaml template.
- name: 'gcr.io/cloud-builders/kubectl'
  args:
  - 'apply'
  - '-f'
  - '-' # Read from stdin
  entrypoint: 'bash'
  script: |
    # Replace the image tag in the deployment-green.yaml template
    # and pipe it to kubectl apply
    sed "s|gcr.io/$PROJECT_ID/my-python-app:v1.1.0|gcr.io/$PROJECT_ID/my-python-app:$COMMIT_SHA|g" deployment-green.yaml | kubectl apply -f -
  id: 'Update Green Deployment'
  waitFor: ['Push Image']

# 4. Perform health checks on the Green environment (Crucial step!)
# This is a placeholder. In a real scenario, you'd use kubectl exec to run
# a script inside a green pod, or query a health endpoint exposed by the app.
# You might also use a separate "canary" ingress or a dedicated testing service.
- name: 'gcr.io/cloud-builders/kubectl'
  args: ['exec', '-it', 'deployment/my-python-app-green', '--', 'echo', 'Health check placeholder']
  id: 'Health Check Green'
  waitFor: ['Update Green Deployment']
  # Add a timeout and retry logic here for robust health checks

# 5. Update the Ingress to point to the Green Service
# This involves patching the existing Ingress resource.
- name: 'gcr.io/cloud-builders/kubectl'
  args:
  - 'patch'
  - 'ingress'
  - 'my-python-app-ingress'
  - '--patch'
  - '{"spec": {"rules": [{"http": {"paths": [{"path": "/", "pathType": "Prefix", "backend": {"service": {"name": "my-python-app-green-svc", "port": {"number": 80}}}}]}}]}}'
  id: 'Switch Traffic to Green'
  waitFor: ['Health Check Green']

# 6. (Optional) Scale down or update Blue deployment
# This step can be added to clean up the old blue deployment or prepare it
# for the next cycle. For now, we'll leave it as a rollback option.
# - name: 'gcr.io/cloud-builders/kubectl'
#   args: ['scale', 'deployment', 'my-python-app-blue', '--replicas=0']
#   id: 'Scale Down Blue'
#   waitFor: ['Switch Traffic to Green']

images:
- 'gcr.io/$PROJECT_ID/my-python-app:$COMMIT_SHA'
options:
  logging: CLOUD_LOGGING_ONLY
substitutions:
  _GKE_CLUSTER_NAME: your-gke-cluster-name
  _GKE_CLUSTER_ZONE: your-gke-cluster-zone # or _GKE_CLUSTER_REGION
  _GCP_PROJECT_ID: $PROJECT_ID


Triggering and Managing Deployments

You can trigger this Cloud Build pipeline manually:

gcloud builds submit --config cloudbuild.yaml . --substitutions=_GKE_CLUSTER_NAME=your-gke-cluster-name,_GKE_CLUSTER_ZONE=your-gke-cluster-zone

Alternatively, you can set up Cloud Build triggers to automatically build and deploy on code commits to specific branches (e.g., `main` for production deployments). This enables continuous deployment.

Rollback Strategy

In case of issues with the Green deployment after traffic has been switched, rolling back is straightforward. You simply update the Ingress resource to point back to the Blue Service:

kubectl patch ingress my-python-app-ingress --patch '{"spec": {"rules": [{"http": {"paths": [{"path": "/", "pathType": "Prefix", "backend": {"service": {"name": "my-python-app-blue-svc", "port": {"number": 80}}}}]}}]}}'

The old Blue deployment (now idle or running the old version) becomes the active production environment again. The new Green deployment can then be scaled down, deleted, or updated to the new version for the next deployment cycle.

Advanced Considerations

Health Checks: The placeholder health check in the Cloud Build pipeline is insufficient for production. Implement robust health checks. This could involve:

  • Using Kubernetes Liveness and Readiness probes within your Deployment manifests.
  • Having your application expose a dedicated /healthz endpoint that performs deeper checks.
  • Configuring the GKE Ingress with appropriate health check annotations to ensure traffic is only sent to healthy pods.

Canary Deployments: For even lower risk, you can extend this pattern to a canary release. Instead of switching 100% of traffic at once, you could initially route a small percentage (e.g., 5%) to the Green environment, monitor closely, and gradually increase the percentage.

Database Migrations: Database schema changes are a common challenge. A blue-green deployment strategy requires careful handling of database migrations to ensure backward compatibility between the Blue and Green versions during the transition. This often involves a multi-step process: deploy code that can handle both old and new schema, run migrations, then switch traffic, and finally deploy code that only supports the new schema.

Stateful Applications: For stateful applications, managing persistent data across blue and green environments requires more complex strategies, potentially involving shared storage or advanced data replication techniques.

Cost Optimization: Running two full environments (even if one is idle) can increase costs. Consider strategies like scaling down the idle environment to zero replicas or using GKE Autopilot to manage underlying infrastructure more efficiently.

Understanding the Blue-Green Deployment Pattern

Blue-Green deployment is a strategy for releasing software that minimizes downtime and risk. It involves maintaining two identical production environments, referred to as "Blue" and "Green." At any given time, one environment (e.g., Blue) is serving live production traffic, while the other (e.g., Green) is idle. To deploy a new version, we deploy the new code to the idle environment (Green), test it thoroughly, and then switch the router (e.g., load balancer or DNS) to direct all incoming traffic to the Green environment. The old Blue environment is then kept as a rollback target or updated to the new version for the next deployment cycle.

Leveraging Google Cloud Services for Blue-Green Deployments

Google Cloud Platform (GCP) offers a robust set of services that are well-suited for implementing blue-green deployments for Python applications. We'll focus on using Google Kubernetes Engine (GKE) for container orchestration, Cloud Load Balancing for traffic management, and Cloud Build for CI/CD automation.

Setting Up GKE Clusters

For a blue-green strategy, we need two distinct sets of compute resources that can serve our application. While a single GKE cluster can host both "blue" and "green" deployments using Kubernetes namespaces and selective service routing, a more robust and isolated approach for true blue-green involves two separate GKE clusters. This provides stronger blast radius containment. However, for simplicity and cost-effectiveness, we'll demonstrate using a single GKE cluster with distinct Kubernetes Deployments and Services, managed by a sophisticated ingress controller.

First, ensure you have two GKE clusters provisioned, or one cluster configured to manage distinct environments. For this example, we'll assume a single GKE cluster and use Kubernetes Deployments and Services to differentiate between Blue and Green. We'll also need a mechanism to route traffic. Cloud Load Balancing with GKE Ingress is a powerful choice.

Containerizing Your Python Application

Your Python application needs to be containerized using Docker. A typical Dockerfile for a Python web application (e.g., Flask or Django) might look like this:

# Use an official Python runtime as a parent image
FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Make port 8080 available to the world outside this container
EXPOSE 8080

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

Ensure your requirements.txt lists all necessary Python packages, including your web framework (e.g., Flask, Django) and any WSGI server (e.g., Gunicorn, uWSGI).

Kubernetes Manifests for Blue and Green Deployments

We'll define Kubernetes resources to manage our Blue and Green deployments. The key is to have separate Deployments and Services for each version, and a single Ingress resource that can be dynamically updated to point to the desired Service.

First, let's define the Deployment for the "Blue" version. This will be our current production version.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-python-app-blue
  labels:
    app: my-python-app
    version: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-python-app
      version: blue
  template:
    metadata:
      labels:
        app: my-python-app
        version: blue
    spec:
      containers:
      - name: app
        image: gcr.io/your-gcp-project-id/my-python-app:v1.0.0 # Replace with your image
        ports:
        - containerPort: 8080
        env:
        - name: APP_ENV
          value: "production"

Next, the Service for the "Blue" deployment. This Service will be selected by the Ingress.

apiVersion: v1
kind: Service
metadata:
  name: my-python-app-blue-svc
spec:
  selector:
    app: my-python-app
    version: blue
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: ClusterIP

Now, the Deployment for the "Green" version. This will be our new version, initially not receiving traffic.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-python-app-green
  labels:
    app: my-python-app
    version: green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-python-app
      version: green
  template:
    metadata:
      labels:
        app: my-python-app
        version: green
    spec:
      containers:
      - name: app
        image: gcr.io/your-gcp-project-id/my-python-app:v1.1.0 # Replace with your new image
        ports:
        - containerPort: 8080
        env:
        - name: APP_ENV
          value: "staging" # Or any other indicator for the new version

And the Service for the "Green" deployment.

apiVersion: v1
kind: Service
metadata:
  name: my-python-app-green-svc
spec:
  selector:
    app: my-python-app
    version: green
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: ClusterIP

Configuring Google Cloud Load Balancer (GKE Ingress)

We'll use a single GKE Ingress resource to manage traffic. Initially, it will point to the Blue Service. During the switch, we'll update the Ingress to point to the Green Service.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-python-app-ingress
  annotations:
    kubernetes.io/ingress.class: "gce" # For GKE Ingress Controller
    # Add other annotations for SSL, health checks, etc. as needed
    # e.g., "networking.gke.io/managed-certificates": "my-managed-cert"
spec:
  rules:
  - http:
      paths:
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: my-python-app-blue-svc # Initially points to Blue
            port:
              number: 80

To apply these resources:

kubectl apply -f deployment-blue.yaml
kubectl apply -f service-blue.yaml
kubectl apply -f deployment-green.yaml
kubectl apply -f service-green.yaml
kubectl apply -f ingress.yaml

After applying the Ingress, GCP will provision a Google Cloud Load Balancer. You can find its external IP address using:

kubectl get ingress my-python-app-ingress

The Deployment Pipeline with Cloud Build

We can automate the blue-green deployment process using Cloud Build. This pipeline will:

  • Build the new Docker image for the Green environment.
  • Push the image to Google Container Registry (GCR) or Artifact Registry.
  • Update the Green Deployment with the new image.
  • Perform health checks on the Green environment.
  • Update the Ingress to point to the Green Service.
  • (Optional) Scale down the Blue deployment or prepare it for the next cycle.

Here's a sample cloudbuild.yaml:

steps:
# 1. Build the new Docker image for the Green environment
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/my-python-app:$COMMIT_SHA', '.']
  id: 'Build Image'

# 2. Push the image to GCR
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'gcr.io/$PROJECT_ID/my-python-app:$COMMIT_SHA']
  id: 'Push Image'

# 3. Update the Green Deployment with the new image
# This step requires kubectl configured for your GKE cluster.
# We'll use kustomize or sed to update the image tag in the deployment manifest.
# For simplicity, let's assume we have a deployment-green.yaml template.
- name: 'gcr.io/cloud-builders/kubectl'
  args:
  - 'apply'
  - '-f'
  - '-' # Read from stdin
  entrypoint: 'bash'
  script: |
    # Replace the image tag in the deployment-green.yaml template
    # and pipe it to kubectl apply
    sed "s|gcr.io/$PROJECT_ID/my-python-app:v1.1.0|gcr.io/$PROJECT_ID/my-python-app:$COMMIT_SHA|g" deployment-green.yaml | kubectl apply -f -
  id: 'Update Green Deployment'
  waitFor: ['Push Image']

# 4. Perform health checks on the Green environment (Crucial step!)
# This is a placeholder. In a real scenario, you'd use kubectl exec to run
# a script inside a green pod, or query a health endpoint exposed by the app.
# You might also use a separate "canary" ingress or a dedicated testing service.
- name: 'gcr.io/cloud-builders/kubectl'
  args: ['exec', '-it', 'deployment/my-python-app-green', '--', 'echo', 'Health check placeholder']
  id: 'Health Check Green'
  waitFor: ['Update Green Deployment']
  # Add a timeout and retry logic here for robust health checks

# 5. Update the Ingress to point to the Green Service
# This involves patching the existing Ingress resource.
- name: 'gcr.io/cloud-builders/kubectl'
  args:
  - 'patch'
  - 'ingress'
  - 'my-python-app-ingress'
  - '--patch'
  - '{"spec": {"rules": [{"http": {"paths": [{"path": "/", "pathType": "Prefix", "backend": {"service": {"name": "my-python-app-green-svc", "port": {"number": 80}}}}]}}]}}'
  id: 'Switch Traffic to Green'
  waitFor: ['Health Check Green']

# 6. (Optional) Scale down or update Blue deployment
# This step can be added to clean up the old blue deployment or prepare it
# for the next cycle. For now, we'll leave it as a rollback option.
# - name: 'gcr.io/cloud-builders/kubectl'
#   args: ['scale', 'deployment', 'my-python-app-blue', '--replicas=0']
#   id: 'Scale Down Blue'
#   waitFor: ['Switch Traffic to Green']

images:
- 'gcr.io/$PROJECT_ID/my-python-app:$COMMIT_SHA'
options:
  logging: CLOUD_LOGGING_ONLY
substitutions:
  _GKE_CLUSTER_NAME: your-gke-cluster-name
  _GKE_CLUSTER_ZONE: your-gke-cluster-zone # or _GKE_CLUSTER_REGION
  _GCP_PROJECT_ID: $PROJECT_ID


Triggering and Managing Deployments

You can trigger this Cloud Build pipeline manually:

gcloud builds submit --config cloudbuild.yaml . --substitutions=_GKE_CLUSTER_NAME=your-gke-cluster-name,_GKE_CLUSTER_ZONE=your-gke-cluster-zone

Alternatively, you can set up Cloud Build triggers to automatically build and deploy on code commits to specific branches (e.g., `main` for production deployments). This enables continuous deployment.

Rollback Strategy

In case of issues with the Green deployment after traffic has been switched, rolling back is straightforward. You simply update the Ingress resource to point back to the Blue Service:

kubectl patch ingress my-python-app-ingress --patch '{"spec": {"rules": [{"http": {"paths": [{"path": "/", "pathType": "Prefix", "backend": {"service": {"name": "my-python-app-blue-svc", "port": {"number": 80}}}}]}}]}}'

The old Blue deployment (now idle or running the old version) becomes the active production environment again. The new Green deployment can then be scaled down, deleted, or updated to the new version for the next deployment cycle.

Advanced Considerations

Health Checks: The placeholder health check in the Cloud Build pipeline is insufficient for production. Implement robust health checks. This could involve:

  • Using Kubernetes Liveness and Readiness probes within your Deployment manifests.
  • Having your application expose a dedicated /healthz endpoint that performs deeper checks.
  • Configuring the GKE Ingress with appropriate health check annotations to ensure traffic is only sent to healthy pods.

Canary Deployments: For even lower risk, you can extend this pattern to a canary release. Instead of switching 100% of traffic at once, you could initially route a small percentage (e.g., 5%) to the Green environment, monitor closely, and gradually increase the percentage.

Database Migrations: Database schema changes are a common challenge. A blue-green deployment strategy requires careful handling of database migrations to ensure backward compatibility between the Blue and Green versions during the transition. This often involves a multi-step process: deploy code that can handle both old and new schema, run migrations, then switch traffic, and finally deploy code that only supports the new schema.

Stateful Applications: For stateful applications, managing persistent data across blue and green environments requires more complex strategies, potentially involving shared storage or advanced data replication techniques.

Cost Optimization: Running two full environments (even if one is idle) can increase costs. Consider strategies like scaling down the idle environment to zero replicas or using GKE Autopilot to manage underlying infrastructure more efficiently.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • CPU-bound Limits: Benchmarking Math Loops and Byte String Manipulation in Pure PHP vs. CPython
  • Migrating ActiveX/COM Components to VB.NET: Resolving Interface Mismatches and Registry Dependencies
  • Single-Threaded Apartment (STA) vs. Free Threading: Managing Thread Safety and Thread Pools in VB.NET
  • WinForms Form Lifecycle vs. Classic VB6 Forms: GDI Paint Loop, Event Dispatching, and DPI Scaling
  • DoEvents Event Yielding vs. Modern Async/Await: Fixing GUI Freeze in Legacy Codebase Modernization

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (583)
  • DevOps (7)
  • DevOps & Cloud Scaling (956)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • MySQL (1)
  • Performance & Optimization (783)
  • PHP (5)
  • PHP Development (14)
  • Plugins & Themes (244)
  • Programming Languages (3)
  • Python (12)
  • Ruby on Rails (1)
  • Security & Compliance (543)
  • SEO & Growth (491)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (7)
  • Web Applications & Frontend (1)
  • WordPress (22)
  • WordPress Plugin Development (7)
  • WordPress Theme Development (357)

Recent Posts

  • CPU-bound Limits: Benchmarking Math Loops and Byte String Manipulation in Pure PHP vs. CPython
  • Migrating ActiveX/COM Components to VB.NET: Resolving Interface Mismatches and Registry Dependencies
  • Single-Threaded Apartment (STA) vs. Free Threading: Managing Thread Safety and Thread Pools in VB.NET
  • WinForms Form Lifecycle vs. Classic VB6 Forms: GDI Paint Loop, Event Dispatching, and DPI Scaling
  • DoEvents Event Yielding vs. Modern Async/Await: Fixing GUI Freeze in Legacy Codebase Modernization
  • P/Invoke and Marshal APIs: Interoping Legacy C-Dlls and Structs from Modernized VB.NET Systems

Top Categories

  • DevOps & Cloud Scaling (956)
  • Performance & Optimization (783)
  • Debugging & Troubleshooting (583)
  • Security & Compliance (543)
  • SEO & Growth (491)
  • Business & Monetization (390)

Our Products

  • School Management & Student Administration System
  • Integrated Hospital & Clinic Management System
  • Real Estate Directory & Agent Portal
  • Restaurant POS & Table Booking System
  • Retail Inventory POS & Billing System
  • Pharmacy Inventory & Clinic Billing System

Our Services

  • Vibe Engineering & AI Code Auditing Services
  • Prompt Engineering & "Vibe Coding" Workflow Consulting
  • AI-Augmented "Vibe Coding" & Rapid MVP Development
  • Figma to Shopify Liquid Theme Customization
  • Figma to WooCommerce Frontend Development
  • Figma to Magento 2 Theme Development

Copyright © 2026 · Vinay Vengala