Skip to main content

Lab 005: Deploy Drupal on Kubernetes



Requirements

The Nautilus Application Development team is planning to deploy Drupal application on Kubernetes cluster as part of their infrastructure modernization initiative. Drupal is a powerful and flexible content management system that requires database backend and persistent storage for proper operation.

The deployment should include:

  • MySQL or MariaDB database backend
  • Drupal application deployment with persistent storage for file uploads and configurations
  • Service to expose Drupal externally via NodePort
  • ConfigMap for Drupal configuration
  • Secrets for database credentials

Note

This lab demonstrates deploying a full-stack content management system on Kubernetes with proper separation of concerns using Deployments, Services, ConfigMaps, and Secrets.

Prerequisites

  • Access to Kubernetes cluster via kubectl
  • kubectl configured to work with the target cluster
  • Sufficient cluster resources for Drupal and MySQL deployments
  • Understanding of multi-tier application deployment patterns

Steps

Create the necessary Kubernetes manifests for Drupal deployment:

# Step 1: Create database secret
apiVersion: v1
kind: Secret
metadata:
name: drupal-db-secret
type: Opaque
stringData:
username: drupal_user
password: drupal_secure_password
database: drupal_db
---
# Step 2: Create MySQL deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: drupal-db-secret
key: password
- name: MYSQL_DATABASE
valueFrom:
secretKeyRef:
name: drupal-db-secret
key: database
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: drupal-db-secret
key: username
ports:
- containerPort: 3306
---
# Step 3: Create MySQL service
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
type: ClusterIP
---
# Step 4: Create Drupal deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: drupal-deployment
spec:
replicas: 1
selector:
matchLabels:
app: drupal
template:
metadata:
labels:
app: drupal
spec:
containers:
- name: drupal
image: drupal:9-apache
ports:
- containerPort: 80
env:
- name: DRUPAL_DB_HOST
value: mysql-service
- name: DRUPAL_DB_NAME
valueFrom:
secretKeyRef:
name: drupal-db-secret
key: database
- name: DRUPAL_DB_USER
valueFrom:
secretKeyRef:
name: drupal-db-secret
key: username
- name: DRUPAL_DB_PASSWORD
valueFrom:
secretKeyRef:
name: drupal-db-secret
key: password
volumeMounts:
- name: drupal-storage
mountPath: /var/www/html/sites/default/files
volumes:
- name: drupal-storage
emptyDir: {}
---
# Step 5: Create Drupal service
apiVersion: v1
kind: Service
metadata:
name: drupal-service
spec:
type: NodePort
selector:
app: drupal
ports:
- port: 80
targetPort: 80
nodePort: 30080

Apply the manifests:

# Apply all resources
kubectl apply -f drupal-deployment.yaml

# Monitor deployment
kubectl get deployments
kubectl get services
kubectl get pods

Verification

Verify that both MySQL and Drupal deployments are running properly:

# Check MySQL deployment
kubectl get deployment mysql-deployment
kubectl get service mysql-service

# Check Drupal deployment
kubectl get deployment drupal-deployment
kubectl get service drupal-service

# Check pod status
kubectl get pods

# View logs
kubectl logs deployment/mysql-deployment
kubectl logs deployment/drupal-deployment

# Access Drupal
# Via NodePort: http://<node-ip>:30080
# Via port-forward: kubectl port-forward service/drupal-service 8080:80

Resources