Deploy Drupal App on Kubernetes
I’m a hands-on software engineer with over 18 years of experience solving real-world problems with code. I’ve spent most of that time building web applications, backend systems, and automation tools — often using Python, Django, REST, and a healthy mix of SQL and shell scripts on Linux.
Along the way, I’ve also picked up frontend work with Angular and React, and built infrastructure using Docker, Kubernetes, AWS, and Terraform. I wouldn’t call myself a DevOps engineer, but I do believe in owning the full stack — from writing the API to making sure it runs smoothly in production.
I’ve worked in all kinds of teams — large, small, remote, distributed, fast-paced, slow-paced. For the last few years, I’ve been freelancing, which has been both freeing and demanding in the best possible way. It’s pushed me to keep learning, stay sharp, and step outside my comfort zone. I love the mix of flexibility and challenge it brings.
This is part four of a series of lab tasks from KodeKloud for Kubernetes level 4. Master blog listing all parts can be seen here. Make sure to follow setup instructions for minikube on your PC.
Problem with Inline Solutions
We need to deploy a Drupal application on Kubernetes cluster. The Nautilus application development team want to setup a fresh Drupal as they will do the installation on their own. Below you can find the requirements, they have shared with us.
Configure a persistent volume
drupal-mysql-pvwithhostPath = /drupal-mysql-data(/drupal-mysql-datadirectory already exists on the worker Node i.e jump host),5Giof storage and ReadWriteOnce access mode.apiVersion: v1 kind: PersistentVolume metadata: name: drupal-mysql-pv # Make sure matches with requirement labels: type: local spec: storageClassName: standard capacity: storage: 5Gi # Important accessModes: - ReadWriteOnce hostPath: path: "/drupal-mysql-data" persistentVolumeReclaimPolicy: RetainConfigure one PersistentVolumeClaim named
drupal-mysql-pvcwith storage request of3Giand ReadWriteOnce access mode.apiVersion: v1 kind: PersistentVolumeClaim # Important, the type of object metadata: name: drupal-mysql-pvc # Again, must match with spec labels: app: mysql-app spec: storageClassName: standard accessModes: - ReadWriteOnce resources: requests: storage: 3Gi # Spec!Create a deployment
drupal-mysqlwith1replica, usemysql:5.7image. Mount the claimed PVC at/var/lib/mysql.First create secrets that'll be used by MySQL spec:
$ kubectl create secret generic mysql-root-pass \ --from-literal=password=YUIidhb667 $ kubectl create secret generic mysql-user-pass \ --from-literal=username=kodekloud_cap \ --from-literal=password=ksH85UJjhb $ kubectl create secret generic mysql-db-url \ --from-literal=database=kodekloud_db2apiVersion: apps/v1 kind: Deployment metadata: name: drupal-mysql labels: app: mysql-app spec: replicas: 1 selector: matchLabels: app: mysql-app tier: mysql strategy: type: Recreate template: metadata: labels: app: mysql-app tier: mysql spec: containers: - image: mysql:5.7 name: mysql env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-root-pass key: password - name: MYSQL_DATABASE valueFrom: secretKeyRef: name: mysql-db-url key: database - name: MYSQL_USER valueFrom: secretKeyRef: name: mysql-user-pass key: username - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: mysql-user-pass key: password ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: drupal-mysql-pvcCreate a deployment
drupalwith1replica and usedrupal:8.6image.apiVersion: apps/v1 kind: Deployment metadata: name: drupal labels: app: drupal-app spec: replicas: 1 selector: matchLabels: app: drupal-app tier: drupal-back-end strategy: type: Recreate template: metadata: labels: app: drupal-app tier: drupal-back-end spec: containers: - image: drupal:8.6 name: drupal ports: - containerPort: 80 name: drupalCreate a NodePort type service which should be named as
drupal-serviceand nodePort should be30095.apiVersion: v1 kind: Service metadata: name: drupal-service labels: app: drupal-app spec: type: NodePort ports: - targetPort: 80 port: 80 nodePort: 30095 selector: app: drupal-app tier: drupal-back-endCreate a service drupal-mysql-service to expose mysql deployment on port 3306.
apiVersion: v1 kind: Service metadata: name: drupal-mysql-service labels: app: mysql-app spec: type: NodePort ports: - targetPort: 3306 port: 3306 nodePort: 30096 selector: app: mysql-app tier: mysqlSet rest of the configration for deployments, services, secrets etc as per your preferences. At the end you should be able to access the Drupal installation page by clicking on App button.
Note: The kubectl on jump_host has been configured to work with the kubernetes cluster.

