Skip to main content

Drupal

Introduction

Getting Started

  1. First create a new GitLab project using the instance template from the AppBase for your language (PHP).
    • The AppBase will provide you with a pattern to deploy applications
    • Will automatically setup GitLab CI/CD tools such as security settings
    • The quickest way to get up and running with OpenShift.
    • Read the README.md file in the repository for latest instructions and notes for your framework.

TODO:

  1. OpenShift notes

Notes

Authentication

Authentication of Azure AD

In app Auth

To setup Drupal auth use Azure AD

Assigning access

To add user accounts there's three parts, code, dev, prod.

Drush admin access
vendor/drush/drush/drush user:create your_user_name --mail="your_user_email@email.com" --password="your user password"
vendor/drush/drush/drush user:role:add "administrator" your_user_name

Code

Adding GitLab code access

  1. Open the project
  2. Click on Members
  3. Search the username provided (if there's no results request the user to login to GitLab)
  4. Assign the user Maintainer access
  5. If there's a contract termination point set the expiry

Adding user to OpenShift project

** Note: do steps for both non-prod and prod environments.

  1. Login to OpenShift

Composer memory limits

If developer is unable to run a Drupal update due to a memory alert error such as below:

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes)

Advise the dev to add the following parameter to their composer CLI command COMPOSER_MEMORY_LIMIT=-1

Composer older version

Add a variable to the build config

COMPOSER_INSTALLER
https://devops.novascotia.ca/assets/files/installer

Syncing files

Clients some times will request files to be moved from dev to prod. This requires syncing the files which should be done on a server in the PDC with access to the oc command

First set a namespace

export NAMESPACE="tourism"

Login to dev and copy the files locally to files folder

oc login https://api.nonprod.novascotia.ca:6443
oc project $NAMESPACE-dev
export POD_NAME=`oc get pods | grep app | grep -m1 -i running | cut -f1 -d" "`
oc rsync $POD_NAME:/opt/app-root/src/web/sites/default/files/ files

Login to prod and send the files to the running pod

oc login https://api.prod.novascotia.ca:6443
oc project $NAMESPACE-prod
export POD_NAME=`oc get pods | grep app | grep -m1 -i running | cut -f1 -d" "`
oc rsync files/ $POD_NAME:/opt/app-root/src/web/sites/default/files

Syncing database

Clients some times need to copy dev database to prod. You need to do this on a server with the MySQL command and mysqldump.

export NAMESPACE="tourism"
mkdir files

To dump dev

oc login https://api.nonprod.novascotia.ca:6443
oc project $NAMESPACE-dev
export DRUPAL_DATABASE=`oc get secret/drupal-mysqldb -o yaml -o jsonpath="{.data.DRUPAL_DATABASE}" | base64 --decode`
export DRUPAL_DATABASE_HOST=`oc get secret/drupal-mysqldb -o yaml -o jsonpath="{.data.DRUPAL_DATABASE_HOST}" | base64 --decode`
export DRUPAL_DATABASE_USER=`oc get secret/drupal-mysqldb -o yaml -o jsonpath="{.data.DRUPAL_DATABASE_USER}" | base64 --decode`
export DRUPAL_DATABASE_PASSWORD=`oc get secret/drupal-mysqldb -o yaml -o jsonpath="{.data.DRUPAL_DATABASE_PASSWORD}" | base64 --decode`
mysqldump -u ${DRUPAL_DATABASE_USER} -h ${DRUPAL_DATABASE_HOST} -p${DRUPAL_DATABASE_PASSWORD} --single-transaction ${DRUPAL_DATABASE} > dev_db.sql

If your using a newer version of MySQL you will get an error like Unknown table 'COLUMN_STATISTICS' in information_schema (1109). In order to resolve this you need to ignore the statistics column like below.

If your using a HA database setup like in Azure or AWS you need to exclude the global id's to make sure the database restore will work. You will see errors like ERROR 1227 (42000) at line 24: Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation so use the parameter --set-gtid-purged=OFF.

mysqldump  --column-statistics=0 -u ${DRUPAL_DATABASE_USER} -h ${DRUPAL_DATABASE_HOST} -p${DRUPAL_DATABASE_PASSWORD} --single-transaction ${DRUPAL_DATABASE} > dev_db.sql

To push to prod

oc login https://api.prod.novascotia.ca:6443
oc project $NAMESPACE-prod
export DRUPAL_DATABASE=`oc get secret/drupal-mysqldb -o yaml -o jsonpath="{.data.DRUPAL_DATABASE}" | base64 --decode`
export DRUPAL_DATABASE_HOST=`oc get secret/drupal-mysqldb -o yaml -o jsonpath="{.data.DRUPAL_DATABASE_HOST}" | base64 --decode`
export DRUPAL_DATABASE_USER=`oc get secret/drupal-mysqldb -o yaml -o jsonpath="{.data.DRUPAL_DATABASE_USER}" | base64 --decode`
export DRUPAL_DATABASE_PASSWORD=`oc get secret/drupal-mysqldb -o yaml -o jsonpath="{.data.DRUPAL_DATABASE_PASSWORD}" | base64 --decode`
cat dev_db.sql | mysql -h ${DRUPAL_DATABASE_HOST} -u ${DRUPAL_DATABASE_USER} -p${DRUPAL_DATABASE_PASSWORD} ${DRUPAL_DATABASE}

Once the db has been reloaded you really should do a cache rebuild

oc login https://api.prod.novascotia.ca:6443
oc project $NAMESPACE-prod
export POD_NAME=`oc get pods | grep app | grep -m1 -i running | cut -f1 -d" "`
oc rsh $POD_NAME vendor/drush/drush/drush cr

Sane defaults for scanning

Works for tenable.io scanning

Environment variable max PHP RAM

            - name: PHP_MEMORY_LIMIT
value: 512M

Resource limits

        - resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 5m
memory: 512Mi

liveness/readiness probes (note below looks for /README.txt as some indicator the site is functioning)

          readinessProbe:
httpGet:
path: /README.txt
port: 8080
scheme: HTTP
initialDelaySeconds: 120
timeoutSeconds: 4
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 120
timeoutSeconds: 2
periodSeconds: 10
successThreshold: 1
failureThreshold: 3

Testing Drupal databases

Some times there might be a requirement to confirm database access. From a pod terminal you can do this via

mysql -u ${DRUPAL_DATABASE_USER} -h ${DRUPAL_DATABASE_HOST} -p${DRUPAL_DATABASE_PASSWORD} ${DRUPAL_DATABASE}

If you had to do work on MSSQL.

/opt/mssql-tools/bin/sqlcmd -S ${DATABASE_HOST} -U ${DATABASE_USER} -P '${DATABASE_PASSWORD}'

Logging IP

In order to fix the logging IP from the x-forwarded-for from the F5 we need to put in a custom logging as either a file in httpd-cfg or map in a ConfigMap like below.

ConfigMap

Setup a ConfigMap with the logging

apiVersion: v1
kind: ConfigMap
metadata:
name: logging-conf
data:
99-logging.conf: |-
<IfModule log_config_module>
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b" common

<IfModule logio_module>
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>

CustomLog "|/usr/bin/cat" combined
</IfModule>

Map to the Deployment or DeploymentConfig

In the volume spec

        - name: logging-conf
configMap:
name: logging-conf
defaultMode: 420

In the container spec

            - name: logging-conf
readOnly: true
mountPath: /opt/app-root/src/httpd-cfg/99-logging.conf
subPath: 99-logging.conf