Kubernetes: Use Helm to Deploy WordPress

Deploying WordPress in a Kubernetes cluster isn’t as straight-forward is one might expect. As the whole infrastructure is controlled by K8s, the deployed containers must be configured with the correct permissions to avoid strange issues. For example, there are certain plugins such as NextGen Gallery that would seem to work fine (initially) in a WordPress instance; however, it would suddenly ‘break’ as CSS and JS (JavaScripts) are showing 404’s. Specially, lightbox and other gallery views functions would become orphanated to leave a Gallery view without slideshow, multi-column views, and other animations. Hence, there are many lesion-learned prior issuing this blog post…

Step 1: Prepare an SSL Cert using LetsEncrypt

# Create SSL Cert, assuming the certmanager has been deployed in the Kubernetes cluster
appName=kimconnect
domainName=kimconnect.com
cat <<EOF > $appName-cert.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: $appName-cert
  namespace: $appName
  annotations:
    kubernetes.io/ingress.class: "nginx"
    acme.cert-manager.io/http01-edit-in-place: "true"
    kubernetes.io/tls-acme: "true"
spec:
  dnsNames:
    - $domainName
  secretName: $appName-cert
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
EOF
kubectl apply -f $appName-cert.yaml

Step 2: Deploy WordPress

# Create name space and enter it
appName=kimconnect
kubectl create namespace $appName
kubectl config set-context --current --namespace=$appName

# Install WordPress with Dynamic NFS Provisioning

# Documentation: https://hub.kubeapps.com/charts/bitnami/wordpress
# Set variables
appName=kimconnect
domainName=kimconnect.com
wordpressusername=kimconnect
wordpressPassword=SOMEVERYCOMPLEXPASSWORD
rootPassword=SOMEVERYCOMPLEXPASSWORD
storageClass=nfs-client

helm install $appName bitnami/wordpress \
  --set readinessProbe.enabled=false \
  --set image.tag=latest \
  --set persistence.accessMode=ReadWriteMany \
  --set persistence.storageClass=$storageClass \
  --set persistence.size=10Ti \
  --set mariadb.primary.persistence.storageClass=$storageClass \
  --set mariadb.primary.persistence.size=300Gi \
  --set wordpressUsername=$wordpressusername \
  --set wordpressPassword=$wordpressPassword \
  --set mariadb.auth.rootPassword=$rootPassword \
  --set mariadb.auth.password=$rootPassword \
  --set ingress.enabled=true,ingress.hostname=$domainName \
  --set volumePermissions.enabled=true \
  --set allowEmptyPassword=false \
  --set service.externalTrafficPolicy=Local # this setting is to make sure the source IP address is preserved.

Step 3: Patch Ingress

# Patch the deployed ingress with an existing SSL cert
appName=kimconnect
domainName=kimconnect.com
certName=$appName-cert
serviceName=$appName-wordpress
cat <<EOF> $appName-patch.yaml
metadata:
  Annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      location ~ /wp-admin$ {
           return 301 /wp-admin/;
       }    
spec:
  tls:
  - hosts:
    - $domainName
    secretName: $certName
  rules:
  - host: $domainName
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: $serviceName
            port:
              number: 80
EOF
kubectl patch ingress/$appName-wordpress -p "$(cat $appName-patch.yaml)"

Step 4: Patch WordPress to Add Libraries and Frameworks

# Still researching this item
# Add iocube loader while inside the container

sed -i '/\[PHP\]/a zend_extension=/bitnami/wordpress/extensions/ioncube_loader_lin_7.4.so' /opt/bitnami/php/etc/php.ini && httpd -k restart

Leave a Reply

Your email address will not be published. Required fields are marked *