Dockerizing and Orchestrating Legacy WooCommerce Systems on Modern Google Cloud Infrastructure
Deconstructing the Monolith: Initial Dockerization Strategy
Migrating a legacy WooCommerce installation, often a tightly coupled monolith, into containers requires a phased approach. The primary goal is to isolate the core components: the web server (typically Apache or Nginx), PHP, and the WooCommerce/WordPress application itself. We’ll start by creating a Dockerfile for the application layer.
Consider a typical WooCommerce setup with Apache. We’ll build upon the official WordPress image, layering our customizations on top. This approach leverages existing, well-maintained base images and reduces the complexity of our custom Dockerfile.
Dockerfile for WooCommerce Application
This Dockerfile assumes you have your WooCommerce codebase (including themes and plugins) available in a local directory, typically named ./app relative to the Dockerfile.
# Use an official WordPress image as a base FROM wordpress:latest # Set environment variables for WordPress and WooCommerce ENV WORDPRESS_DB_HOST=db:3306 ENV WORDPRESS_DB_USER=wordpress ENV WORDPRESS_DB_PASSWORD=wordpress ENV WORDPRESS_DB_NAME=wordpress # Install necessary PHP extensions for WooCommerce and common plugins # Example: Imagick for image manipulation, ZipArchive for plugin updates RUN docker-php-ext-install gd zip imagick && docker-php-ext-enable gd zip imagick # Copy your custom WooCommerce theme and plugins into the container # Ensure these directories exist locally and contain your code COPY ./app/wp-content/themes/your-theme /var/www/html/wp-content/themes/your-theme COPY ./app/wp-content/plugins/your-plugin-1 /var/www/html/wp-content/plugins/your-plugin-1 COPY ./app/wp-content/plugins/your-plugin-2 /var/www/html/wp-content/plugins/your-plugin-2 # Copy any custom WordPress configurations or core modifications # Be cautious with core modifications; prefer plugins/themes COPY ./app/wp-config.php /var/www/html/wp-config.php # Set correct permissions for web server user RUN chown -R www-data:www-data /var/www/html/wp-content # Expose the default WordPress port EXPOSE 80 # The default command from the base image will start Apache and PHP-FPM # CMD ["apache2-foreground"] # This is inherited from the base image
Database Containerization: MySQL/MariaDB
A separate container for the database is crucial for scalability and maintainability. We’ll use the official MySQL or MariaDB image.
Docker Compose for Orchestration
docker-compose.yml orchestrates the application and database containers, defining their relationships, networks, and volumes.
version: '3.8'
services:
db:
image: mysql:8.0
container_name: woocommerce_db
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: your_root_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
networks:
- woocommerce_network
wordpress:
build:
context: .
dockerfile: Dockerfile
container_name: woocommerce_app
ports:
- "8080:80" # Map host port 8080 to container port 80
depends_on:
- db
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_content:/var/www/html/wp-content # Persist wp-content
- wp_uploads:/var/www/html/wp-content/uploads # Persist uploads
restart: always
networks:
- woocommerce_network
volumes:
db_data:
wp_content:
wp_uploads:
networks:
woocommerce_network:
driver: bridge
To build and run this setup locally:
# Navigate to the directory containing your Dockerfile and docker-compose.yml cd /path/to/your/project # Build the Docker images docker-compose build # Start the containers docker-compose up -d
Google Cloud Infrastructure: GKE and Cloud SQL
For production, we’ll leverage Google Kubernetes Engine (GKE) for orchestration and Cloud SQL for managed database services. This offloads database management and provides a robust, scalable platform for our containers.
Migrating to GKE
The docker-compose.yml file serves as a blueprint for Kubernetes manifests. We’ll translate services into Deployments, Services, and PersistentVolumeClaims.
Kubernetes Manifests (YAML)
Here’s a simplified representation of Kubernetes manifests for our WooCommerce setup. This assumes you’ve already provisioned a Cloud SQL instance and have its connection details.
Cloud SQL Proxy Sidecar Pattern
To securely connect to Cloud SQL from GKE, the recommended approach is to use the Cloud SQL Auth Proxy as a sidecar container within your application pod. This avoids exposing your database directly and handles authentication via IAM.
# wordpress-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: woocommerce-app
labels:
app: woocommerce
spec:
replicas: 3 # Adjust as needed for scalability
selector:
matchLabels:
app: woocommerce
template:
metadata:
labels:
app: woocommerce
spec:
containers:
- name: wordpress
image: gcr.io/your-gcp-project-id/woocommerce-app:latest # Replace with your GCR image
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: "127.0.0.1:3306" # Connect to the sidecar proxy
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: cloudsql-credentials
key: username
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: cloudsql-credentials
key: password
- name: WORDPRESS_DB_NAME
valueFrom:
secretKeyRef:
name: cloudsql-credentials
key: dbname
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html/wp-content
- name: cloudsql-proxy-credentials
mountPath: /secrets/cloudsql
readOnly: true
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.33.0 # Use a specific, stable version
command:
- "/cloud_sql_proxy"
- "-instances=your-gcp-project-id:us-central1:your-cloudsql-instance-name=tcp:3306" # Replace with your instance connection name
- "-credential_file=/secrets/cloudsql/credentials.json"
volumeMounts:
- name: cloudsql-proxy-credentials
mountPath: /secrets/cloudsql
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: woocommerce-pvc
- name: cloudsql-proxy-credentials
secret:
secretName: cloudsql-credentials
---
# wordpress-service.yaml
apiVersion: v1
kind: Service
metadata:
name: woocommerce-service
spec:
selector:
app: woocommerce
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer # Or ClusterIP if using an Ingress controller
---
# woocommerce-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: woocommerce-pvc
spec:
accessModes:
- ReadWriteOnce # Or ReadWriteMany if using shared storage like NFS
resources:
requests:
storage: 10Gi # Adjust size as needed
Secrets Management for Cloud SQL
The database credentials (username, password, database name) for Cloud SQL need to be securely managed. Kubernetes Secrets are the standard way to handle this. You’ll need to create a Kubernetes Secret containing these details and a service account key JSON file for the Cloud SQL Auth Proxy.
# 1. Create a Kubernetes Secret for DB credentials kubectl create secret generic cloudsql-credentials \ --from-literal=username='your_cloudsql_db_user' \ --from-literal=password='your_cloudsql_db_password' \ --from-literal=dbname='your_cloudsql_db_name' # 2. Create a Kubernetes Secret for the Cloud SQL Auth Proxy service account key # (Ensure your GKE cluster has the necessary IAM permissions for this service account) kubectl create secret generic cloudsql-credentials \ --from-file=credentials.json=/path/to/your/service-account-key.json
Deployment to GKE
First, ensure your Docker image is built and pushed to Google Container Registry (GCR) or Artifact Registry.
# Build your Docker image (from your local Dockerfile) docker build -t gcr.io/your-gcp-project-id/woocommerce-app:latest . # Push the image to GCR docker push gcr.io/your-gcp-project-id/woocommerce-app:latest
Then, apply your Kubernetes manifests:
# Apply the PersistentVolumeClaim kubectl apply -f woocommerce-pvc.yaml # Apply the Deployment kubectl apply -f wordpress-deployment.yaml # Apply the Service kubectl apply -f woocommerce-service.yaml
Ingress and SSL Configuration
For production, you’ll want to use a Kubernetes Ingress controller (like GKE’s built-in Load Balancer or Nginx Ingress Controller) to manage external access, SSL termination, and potentially path-based routing. This involves creating an Ingress resource that points to your woocommerce-service.
# ingress.yaml (Example for GKE LoadBalancer)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: woocommerce-ingress
annotations:
kubernetes.io/ingress.class: "gce" # For GKE's managed LoadBalancer
# Add cert-manager annotations for automatic SSL if using it
# cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
rules:
- http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: woocommerce-service
port:
number: 80
# tls: # Uncomment and configure if using TLS
# - hosts:
# - your-domain.com
# secretName: woocommerce-tls-secret # Secret containing your TLS certificate
Apply the Ingress resource:
kubectl apply -f ingress.yaml
Monitoring and Logging
Integrate with Google Cloud’s operations suite (formerly Stackdriver) for comprehensive monitoring and logging. GKE automatically integrates with Cloud Logging and Cloud Monitoring. Ensure your application logs are written to standard output (stdout/stderr) for easy collection.
Performance Tuning and Scaling
Leverage GKE’s Horizontal Pod Autoscaler (HPA) to automatically scale your WooCommerce pods based on CPU or memory utilization. For Cloud SQL, utilize its read replicas and appropriate machine types for your workload.
# hpa.yaml
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: woocommerce-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: woocommerce-app
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # Scale up when CPU utilization reaches 70%
Apply the HPA configuration:
kubectl apply -f hpa.yaml
Conclusion and Next Steps
This guide provides a foundational approach to containerizing and orchestrating legacy WooCommerce systems on Google Cloud. Key considerations for production include robust CI/CD pipelines for automated image building and deployment, advanced security practices (e.g., network policies, IAM roles), and continuous performance monitoring and optimization. The transition to a microservices architecture for specific WooCommerce functionalities (e.g., order processing, product catalog) can be a subsequent step for further scalability and resilience.