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

Vengala Vinay

Having 9+ Years of Experience in Software Development

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

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

Understanding the Blue-Green Deployment Pattern

The blue-green deployment strategy is a technique 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 (Green) is idle. To deploy a new version, the new code is deployed to the idle environment (Green). Once tested and validated, traffic is switched from the Blue environment to the Green environment. The Blue environment then becomes the idle environment, ready for the next deployment.

This approach offers several key advantages:

  • Zero Downtime: Traffic is switched instantaneously, eliminating user-facing downtime.
  • Instant Rollback: If issues arise with the new deployment, traffic can be immediately switched back to the stable Blue environment.
  • Reduced Risk: Testing and validation can be performed on the Green environment without impacting live users.

Google Cloud Infrastructure for Blue-Green Deployments

On Google Cloud Platform (GCP), we can leverage several services to implement a robust blue-green deployment pipeline for PHP applications. The core components will include:

  • Google Kubernetes Engine (GKE): For container orchestration, managing our application deployments.
  • Cloud Load Balancing: To manage traffic routing between the Blue and Green environments.
  • Cloud Build: For automating the build, test, and deployment process.
  • Artifact Registry (or Container Registry): To store our container images.
  • Cloud Storage: Potentially for storing configuration files or static assets.

Setting Up GKE Clusters and Deployments

We’ll need two distinct GKE clusters, or more practically, two distinct sets of Kubernetes Deployments and Services within a single GKE cluster, each representing a “color.” For simplicity and cost-effectiveness, we’ll demonstrate the latter approach using Kubernetes namespaces and distinct Service definitions.

First, let’s define our Kubernetes manifests. We’ll create separate namespaces for ‘blue’ and ‘green’ environments.

Namespace Definitions

Create two YAML files for namespaces:

namespaces.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: blue
---
apiVersion: v1
kind: Namespace
metadata:
  name: green

Apply these to your GKE cluster:

kubectl apply -f namespaces.yaml

Deployment and Service for the ‘Blue’ Environment

Create a deployment manifest for the blue environment. This assumes you have a Docker image for your PHP application in Artifact Registry, e.g., `us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:blue-v1.0.0`.

php-app-blue.yaml:

This manifest defines a Deployment and a Service for the blue environment. The Service will be of type `NodePort` initially, which will be exposed by the Cloud Load Balancer.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-app-deployment
  namespace: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: php-app
      color: blue
  template:
    metadata:
      labels:
        app: php-app
        color: blue
    spec:
      containers:
      - name: php-app-container
        image: us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:blue-v1.0.0
        ports:
        - containerPort: 80
        env:
        - name: APP_ENV
          value: "production"
        # Add other necessary environment variables and resource limits

---
apiVersion: v1
kind: Service
metadata:
  name: php-app-service
  namespace: blue
spec:
  selector:
    app: php-app
    color: blue
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort # We'll use NodePort to integrate with Cloud Load Balancer

Deployment and Service for the ‘Green’ Environment

Similarly, create a manifest for the green environment. The image tag will differ for new deployments.

php-app-green.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-app-deployment
  namespace: green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: php-app
      color: green
  template:
    metadata:
      labels:
        app: php-app
        color: green
    spec:
      containers:
      - name: php-app-container
        image: us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:green-v1.0.0 # Placeholder for new version
        ports:
        - containerPort: 80
        env:
        - name: APP_ENV
          value: "production"
        # Add other necessary environment variables and resource limits

---
apiVersion: v1
kind: Service
metadata:
  name: php-app-service
  namespace: green
spec:
  selector:
    app: php-app
    color: green
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort # NodePort for integration with Cloud Load Balancer

Apply these manifests to your GKE cluster:

kubectl apply -f php-app-blue.yaml

kubectl apply -f php-app-green.yaml

Configuring Cloud Load Balancing for Traffic Switching

We will use a Google Cloud Load Balancer to direct traffic. The key to blue-green is how we configure the backend services of the load balancer. We’ll create two backend services, each pointing to the `NodePort` of the respective ‘blue’ and ‘green’ Kubernetes Services.

First, identify the `NodePort` assigned to each Kubernetes Service. You can find this by running:

kubectl get svc php-app-service -n blue -o jsonpath='{.spec.ports[0].nodePort}'

And similarly for the green namespace.

Now, let’s set up the load balancer using `gcloud` commands. This example assumes an HTTP(S) Load Balancer. We’ll create a health check, two backend services (one for blue, one for green), a URL map, and a target proxy, and finally a forwarding rule.

Health Check

A health check is crucial for the load balancer to know which backend instances are healthy.

gcloud compute health-checks create http php-app-health-check \
  --request-path=/healthz \
  --port=80 \
  --check-interval=5s \
  --timeout=5s \
  --unhealthy-threshold=2 \
  --healthy-threshold=2

Backend Services

We need to create backend services that point to the GKE nodes and the assigned `NodePort`. Replace `NODE_PORT_BLUE` and `NODE_PORT_GREEN` with the actual ports obtained earlier. Also, replace `GKE_NODE_IP_ADDRESS` with the IP addresses of your GKE nodes (you can get these from `gcloud compute instances list –filter=”name~gke-your-cluster-name”`).

# Backend for Blue environment
gcloud compute backend-services create php-app-backend-blue \
  --protocol=HTTP \
  --port-name=http \
  --health-checks=php-app-health-check \
  --global

# Add GKE nodes as backend instances for Blue
# You'll need to repeat this for each GKE node
gcloud compute backend-services add-backend php-app-backend-blue \
  --instance-group=your-gke-node-instance-group \
  --instance-group-zone=your-gke-zone \
  --global \
  --network-endpoint-group=your-neg-for-blue # If using NEG, otherwise use instance-group

# Backend for Green environment
gcloud compute backend-services create php-app-backend-green \
  --protocol=HTTP \
  --port-name=http \
  --health-checks=php-app-health-check \
  --global

# Add GKE nodes as backend instances for Green
gcloud compute backend-services add-backend php-app-backend-green \
  --instance-group=your-gke-node-instance-group \
  --instance-group-zone=your-gke-zone \
  --global \
  --network-endpoint-group=your-neg-for-green # If using NEG, otherwise use instance-group

Note on Network Endpoint Groups (NEGs): For more advanced and resilient setups, especially with GKE, using Network Endpoint Groups (NEGs) is highly recommended. NEGs allow the load balancer to directly target pods, bypassing the need for `NodePort` and improving efficiency. If using NEGs, you would create them per namespace/service and reference them here instead of instance groups.

URL Map and Target Proxy

The URL map will initially direct all traffic to the ‘blue’ backend service. We’ll update this during the switch.

# Create URL Map
gcloud compute url-maps create php-app-url-map \
  --default-service=php-app-backend-blue

# Create Target HTTP Proxy
gcloud compute target-http-proxies create php-app-http-proxy \
  --url-map=php-app-url-map

# Create Global Forwarding Rule (this is your public IP)
gcloud compute forwarding-rules create php-app-forwarding-rule \
  --global \
  --target-http-proxy=php-app-http-proxy \
  --ports=80

Automating Deployments with Cloud Build

Cloud Build can orchestrate the entire deployment process. We’ll define a `cloudbuild.yaml` file to handle building the Docker image, pushing it to Artifact Registry, and updating the Kubernetes deployments.

`cloudbuild.yaml` for Initial Deployment (Blue)

This configuration builds the image for the blue environment and deploys it.

steps:
# Build the Docker image for the blue environment
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:blue-v1.0.0', '.']
  id: 'Build Blue Image'

# Push the Docker image to Artifact Registry
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:blue-v1.0.0']
  id: 'Push Blue Image'

# Deploy to the blue namespace in GKE
- name: 'gcr.io/cloud-builders/kubectl'
  args:
  - 'apply'
  - '-f'
  - 'php-app-blue.yaml'
  env:
  - 'CLOUDSDK_COMPUTE_ZONE=your-gke-zone'
  - 'CLOUDSDK_CONTAINER_CLUSTER=your-gke-cluster-name'
  id: 'Deploy Blue'

# (Optional) Run integration tests against the blue environment
# - name: '...'
#   args: ['run', 'integration-tests', '--image=us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:blue-v1.0.0']
#   id: 'Test Blue'

# Configure load balancer to point to blue (if not already done)
# This step would typically be done once manually or via IaC
# For subsequent deployments, we'll update the URL map.

images:
- 'us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:blue-v1.0.0'

`cloudbuild.yaml` for Deploying New Version (Green) and Switching Traffic

This is the core of the blue-green deployment. We’ll build the new image, deploy it to the ‘green’ namespace, test it, and then switch the load balancer.

Let’s assume the new version is `green-v1.1.0`.

steps:
# Build the Docker image for the green environment (new version)
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:green-v1.1.0', '.']
  id: 'Build Green Image'

# Push the Docker image to Artifact Registry
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:green-v1.1.0']
  id: 'Push Green Image'

# Deploy to the green namespace in GKE
# We'll need to update the php-app-green.yaml to use the new image tag
# A common pattern is to use templating or dynamic generation of manifests
# For simplicity here, we'll assume the manifest is updated or we use kubectl set image
- name: 'gcr.io/cloud-builders/kubectl'
  args:
  - 'set'
  - 'image'
  - 'deployment/php-app-deployment'
  - 'php-app-container=us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:green-v1.1.0'
  - '-n'
  - 'green'
  env:
  - 'CLOUDSDK_COMPUTE_ZONE=your-gke-zone'
  - 'CLOUDSDK_CONTAINER_CLUSTER=your-gke-cluster-name'
  id: 'Update Green Deployment'

# Wait for the green deployment to be ready (optional but recommended)
# This can be done with kubectl rollout status or custom scripts

# Run integration/smoke tests against the green environment
# You'll need to know the IP of the load balancer or a temporary endpoint
# For this example, we'll assume tests are run against the public IP of the LB
# pointing to the green backend. This requires a temporary switch or a separate test LB.
# A more robust approach is to use a separate test LB or internal testing.
# For simplicity, let's assume we have a way to test the green deployment.

# --- Traffic Switching ---
# Update the URL map to point to the green backend service
- name: 'gcr.io/cloud-builders/gcloud'
  args:
  - 'compute'
  - 'url-maps'
  - 'update'
  - 'php-app-url-map'
  - '--default-service'
  - 'php-app-backend-green'
  - '--global'
  id: 'Switch Traffic to Green'

# (Optional) Update the blue deployment to a new version or scale down
# For a true blue-green, you might deploy the *next* version to blue while green is live.
# Or, you might scale down blue to 0 replicas.

images:
- 'us-central1-docker.pkg.dev/your-gcp-project/your-repo/your-php-app:green-v1.1.0'

Rollback Procedure

If the new deployment (Green) exhibits issues after traffic has been switched, rolling back is as simple as switching the load balancer back to the stable ‘Blue’ environment.

This can be automated in Cloud Build with a separate step or triggered manually:

gcloud compute url-maps update php-app-url-map \
  --default-service=php-app-backend-blue \
  --global

The ‘Blue’ environment (which is now idle) can then be updated with a fix and become the ‘Green’ environment for the next deployment cycle.

Advanced Considerations and Best Practices

Database Migrations

Database schema changes are often the trickiest part of blue-green deployments. A common strategy is to use backward-compatible schema changes. Deploy the new application code that can work with both the old and new schema. Then, perform the schema migration. Finally, deploy the new application code that *requires* the new schema. This phased approach prevents downtime during migrations.

Stateful Applications

For applications with persistent state (e.g., user sessions stored in memory), careful consideration is needed. Using external services like Redis for session management, or ensuring statelessness, is crucial. If state must be maintained, strategies like sticky sessions (though often discouraged) or more complex data synchronization mechanisms might be required.

Testing and Validation

Automated testing is paramount. Implement comprehensive unit, integration, and end-to-end tests. Smoke tests against the newly deployed environment (before traffic switch) are essential. Consider canary deployments as a precursor or alternative to full blue-green for even lower risk.

Infrastructure as Code (IaC)

Managing GKE resources, load balancers, and other GCP components manually is error-prone. Use tools like Terraform or Pulumi to define and manage your infrastructure. This ensures consistency and repeatability for your blue and green environments.

Zero-Downtime PHP Application Considerations

Ensure your PHP application is designed for this pattern. This includes:

  • Graceful Shutdown: Applications should handle SIGTERM signals gracefully, finishing in-flight requests before exiting. Kubernetes will send this signal before terminating pods.
  • Statelessness: Avoid storing session data or application state directly on the application server. Use external services like Redis, Memcached, or a managed database.
  • Configuration Management: Externalize configuration (database credentials, API keys, feature flags) using environment variables or a configuration service. This allows updating configurations without redeploying the application code.
  • Health Check Endpoint: Implement a dedicated health check endpoint (e.g., `/healthz`) that accurately reflects the application’s readiness to serve traffic.

By combining GKE’s orchestration capabilities with Cloud Load Balancing’s traffic management and Cloud Build’s automation, you can establish a robust, zero-downtime blue-green deployment pipeline for your PHP applications on Google Cloud.

Primary Sidebar

A little about the Author

Having 9+ Years of Experience in Software Development.
Expertised in Php Development, WordPress Custom Theme Development (From scratch using underscores or Genesis Framework or using any blank theme or Premium Theme), Custom Plugin Development. Hands on Experience on 3rd Party Php Extension like Chilkat, nSoftware.

Recent Posts

  • Disaster Recovery 101: Architecting Auto-Failovers for Redis and PHP Deployments on OVH
  • How We Audited a High-Traffic WooCommerce Enterprise Stack on Google Cloud and Mitigated Race conditions during high-concurrency payment processing
  • Disaster Recovery 101: Architecting Auto-Failovers for Elasticsearch and Magento 2 Deployments on DigitalOcean
  • An Auditor’s Checklist for Securing WordPress Backends on OVH
  • Step-by-Step: Diagnosing Perl script high CPU throttling due to unoptimized regular expressions on AWS Servers

Copyright © 2026 · Vinay Vengala