Drupal
Introduction
Getting Started
- 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:
- 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
- Open the project
- Click on Members
- Search the username provided (if there's no results request the user to login to GitLab)
- Assign the user Maintainer access
- 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.
- 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