Skip to content

codedropau/drupal-tutorial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Drupal Tutorial

This tutorial walks you through how to deploy Drupal on Kubernetes a minimal set of tools.

Prerequisites

Step 1. Setup a Kubernetes cluster

This tutorial includes a local Kubernetes cluster.

In this step we will provision it.

Using Docker Compose, "up" the cluster.

docker-compose up -d

Next we will configure our command line so the Kubernetes command line (kubectl) can connect to this cluster.

kubectl uses the $KUBECONFIG environment variable to discover the file which contains cluster connection configuration.

This configuration is automatically created by the K3s service running inside the Docker Compose stack.

We can now set the environment variable.

export KUBECONFIG=$(pwd)/.kube/config

Let's verify you can connect to the cluster.

kubectl get pods --all-namespaces

The above command should yield a result similiar to the following:

$ kubectl get pods --all-namespaces

NAMESPACE     NAME                                      READY   STATUS    RESTARTS   AGE
kube-system   local-path-provisioner-58fb86bdfd-wxqhg   1/1     Running   0          35s
kube-system   metrics-server-6d684c7b5-m7hss            1/1     Running   0          35s
kube-system   coredns-d798c9dd-plr6c                    0/1     Running   0          35s

The Docker Compose stack also comes with a Docker Registry.

Now we need to ensure we have a consistent DNS entry inside the cluster and on your local command line.

Add the following record to you local /etc/hosts file.

127.0.0.1 registry.drupal-tutorial.svc.cluster.local

In the next step we will package the Drupal application and push it to this registry.

Step 2. Package

export REGISTRY=registry.drupal-tutorial.svc.cluster.local:5000/project1

# This variable is generally derived from the command: git describe --tags --always
export VERSION=0.0.1

# Builds the Drupal application using Composer.
docker build -t ${REGISTRY}/php:${VERSION} -f dockerfiles/php.dockerfile .

# Builds the Nginx container by copying the application from the PHP image.
docker build -t ${REGISTRY}/nginx:${VERSION} -f dockerfiles/nginx.dockerfile --build-arg PHP_IMAGE=${REGISTRY}/php:${VERSION} .

# Push the images to the registry.
docker push ${REGISTRY}/php:${VERSION}
docker push ${REGISTRY}/nginx:${VERSION}

In the next step we will be deploying the Drupal application.

Step 3. Deploy

export NAMESPACE=project1-dev

# OPTIONAL - Create the namespace if it does not exist.
kubectl create ns $NAMESPACE

# Update the images which will be deployed.
# https://kubectl.docs.kubernetes.io/pages/app_management/container_images.html
kustomize edit set image nginx=$REGISTRY/nginx:$VERSION
kustomize edit set image php=$REGISTRY/php:$VERSION

# Rollout the new version of the application.
# https://kubectl.docs.kubernetes.io/pages/app_management/apply.html
kubectl -n $NAMESPACE apply -k .

We can now verify the application by running the following command:

$ kubectl -n $NAMESPACE get -k .

NAME               DATA   AGE
configmap/drupal   0      8m26s

NAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/drupal   ClusterIP   10.43.106.13   <none>        8080/TCP   8m26s

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/drupal   3/3     3            3           8m26s

NAME                        SCHEDULE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/drupal-cron   @hourly    False     0        <none>          8m26s

NAME                                         REFERENCE           TARGETS           MINPODS   MAXPODS   REPLICAS   AGE
horizontalpodautoscaler.autoscaling/drupal   Deployment/drupal   1%/90%, 0%/300%   2         4         3          8m26s

NAME                                     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/drupal-private     Bound    pvc-9e2725d9-7936-47dd-9ee8-8b773440f1a6   20Gi       RWO            local-path     8m26s
persistentvolumeclaim/drupal-public      Bound    pvc-11828727-0ca8-4941-beb4-3fd9fadeea5a   20Gi       RWO            local-path     8m26s
persistentvolumeclaim/drupal-temporary   Bound    pvc-d8663c34-81f4-4c52-bc7c-c2eb4e1030eb   20Gi       RWO            local-path     8m26s

The deployment will be complete once:

  • The Deployment has 1/1 Ready replicas.
  • The PersistentVolumeClaims have becomes Bound.

Now we configure the application to talk to backend resources.

Step 4. Configure

In this section we will be configuring our application to connect to the MySQL instance already setup on the cluster.

We have the MySQL instace separate to emulate a production setup where the MySQL database is hosted on a managed service.

The Twelve-Factor App manifesto recommends applications store config in the environment, not the application.

We also don't want to use environment variables for security reasons.

To achieve this for Drupal site we:

  • Mount a file with our database credentials: /etc/drupal/config.json
  • Load it using a helper function (see settings.k8s.php).

This is all achieved by a Kubernetes ConfigMap, which we are going to PATCH with our config.json file.

kubectl -n $NAMESPACE patch configmap -p '{"data": {"config.json": "{\"mysql.database\": \"drupal\", \"mysql.username\": \"root\", \"mysql.password\": \"password\", \"mysql.hostname\": \"nonprod.mysql\"}"}}' drupal

Step 5. Verify

To verify this deployment we can install the site and inspect it via our local bowser.

# Install the site using Drush.
kubectl -n $NAMESPACE exec -it -c php deployment/drupal -- vendor/bin/drush site-install standard

# Setup a tunnel to the Drupal application running on the cluster.
kubectl -n $NAMESPACE port-forward deployment/drupal 8080:8080

You can now inspect the site on:

http://127.0.0.1:8080

OPTIONAL - Add to a deployment pipeline

All the above can be automated via a CI/CD pipeline.

The following is a snippet which can be used as part of a deployment pipeline.

export NAMESPACE=project1-dev
export REGISTRY=registry.drupal-tutorial.svc.cluster.local:5000/project1
export VERSION=$(git describe --tags --always)

kustomize edit set image nginx=$REGISTRY:$VERSION
kustomize edit set image php=$REGISTRY:$VERSION

kubectl -n $NAMESPACE apply -k .

kubectl -n $NAMESPACE rollout status -w deployment/drupal
kubectl -n $NAMESPACE exec deployment/drupal -- drush cr

About

Example repository for deploying Drupal on Kubernetes

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published