├── .DS_Store ├── .gitignore ├── php5.6 ├── Dockerfile └── scripts │ ├── pull │ ├── push │ └── init_git.sh ├── php7.0 ├── Dockerfile └── scripts │ ├── pull │ ├── push │ └── init_git.sh ├── gcloud_instructions ├── nickveenhofbe │ ├── nfs-pv-claim.yaml │ ├── nfs-pv.yaml │ ├── lb.yaml │ └── pods.yaml ├── nfs-shared1-pv.yaml ├── nfs-shared1-service.yaml └── nfs-shared1-server.yaml └── README.txt /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickveenhof/drupal-docker-with-volume/HEAD/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | DrupalContainerEngine-f8ef8a6dc869.json 2 | DrupalContainerEngine-sql-865696a5432a.json 3 | .DS_Store -------------------------------------------------------------------------------- /php5.6/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM wodby/php:5.6 2 | 3 | # Add Scripts 4 | ADD scripts/init_git.sh /docker-entrypoint-init.d/init_git.sh 5 | ADD scripts/pull /usr/bin/pull 6 | ADD scripts/push /usr/bin/push -------------------------------------------------------------------------------- /php7.0/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM wodby/php:7.0 2 | 3 | # Add Scripts 4 | ADD scripts/init_git.sh /docker-entrypoint-init.d/init_git.sh 5 | ADD scripts/pull /usr/bin/pull 6 | ADD scripts/push /usr/bin/push 7 | -------------------------------------------------------------------------------- /gcloud_instructions/nickveenhofbe/nfs-pv-claim.yaml: -------------------------------------------------------------------------------- 1 | kind: PersistentVolumeClaim 2 | apiVersion: v1 3 | metadata: 4 | name: nvbenfs 5 | labels: 6 | site: nickveenhofbe 7 | spec: 8 | accessModes: 9 | - ReadWriteMany 10 | resources: 11 | requests: 12 | storage: 10Gi -------------------------------------------------------------------------------- /gcloud_instructions/nfs-shared1-pv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: nfs-shared1-200gb 5 | annotations: 6 | volume.alpha.kubernetes.io/storage-class: standard 7 | spec: 8 | accessModes: [ "ReadWriteOnce" ] 9 | resources: 10 | requests: 11 | storage: 200Gi -------------------------------------------------------------------------------- /gcloud_instructions/nfs-shared1-service.yaml: -------------------------------------------------------------------------------- 1 | kind: Service 2 | apiVersion: v1 3 | metadata: 4 | name: nfs-shared1-server 5 | spec: 6 | ports: 7 | - name: nfs 8 | port: 2049 9 | - name: mountd 10 | port: 20048 11 | - name: rpcbind 12 | port: 111 13 | selector: 14 | role: nfs-shared1-server -------------------------------------------------------------------------------- /gcloud_instructions/nickveenhofbe/nfs-pv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: nvbenfs 5 | labels: 6 | site: nickveenhofbe 7 | spec: 8 | capacity: 9 | storage: 10Gi 10 | accessModes: 11 | - ReadWriteMany 12 | nfs: 13 | # FIXME: use the right IP 14 | server: 10.3.247.140 15 | path: "/nickveenhofbe" -------------------------------------------------------------------------------- /php5.6/scripts/pull: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "$GIT_EMAIL" ]; then 4 | echo "You need to pass the \$GIT_EMAIL variable to the container for this to work" 5 | exit 6 | fi 7 | 8 | if [ -z "$GIT_NAME" ]; then 9 | echo "You need to pass the \$GIT_NAME variable to the container for this to work" 10 | exit 11 | fi 12 | 13 | cd /var/www/html 14 | git pull || exit 1 15 | chown -Rf www-data:www-data /var/www/html 16 | -------------------------------------------------------------------------------- /php7.0/scripts/pull: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "$GIT_EMAIL" ]; then 4 | echo "You need to pass the \$GIT_EMAIL variable to the container for this to work" 5 | exit 6 | fi 7 | 8 | if [ -z "$GIT_NAME" ]; then 9 | echo "You need to pass the \$GIT_NAME variable to the container for this to work" 10 | exit 11 | fi 12 | 13 | cd /var/www/html 14 | git pull || exit 1 15 | chown -Rf www-data:www-data /var/www/html 16 | -------------------------------------------------------------------------------- /gcloud_instructions/nickveenhofbe/lb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nickveenhofbe 5 | labels: 6 | site: nickveenhofbe 7 | spec: 8 | type: LoadBalancer 9 | ports: 10 | - name: http 11 | port: 80 12 | targetPort: 80 13 | protocol: TCP 14 | - name: https 15 | port: 443 16 | targetPort: 80 17 | protocol: TCP 18 | selector: 19 | service: nickveenhofbe -------------------------------------------------------------------------------- /php5.6/scripts/push: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | timestamp() { 4 | date +"%D %T" 5 | } 6 | 7 | if [ -z "$GIT_EMAIL" ]; then 8 | echo "You need to pass the \$GIT_EMAIL variable to the container for this to work" 9 | exit 10 | fi 11 | 12 | if [ -z "$GIT_NAME" ]; then 13 | echo "You need to pass the \$GIT_NAME variable to the container for this to work" 14 | exit 15 | fi 16 | 17 | ts=$(timestamp) 18 | cd /var/www/html 19 | git add . 20 | git commit -a -m "push from container $ts" 21 | git push 22 | -------------------------------------------------------------------------------- /php7.0/scripts/push: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | timestamp() { 4 | date +"%D %T" 5 | } 6 | 7 | if [ -z "$GIT_EMAIL" ]; then 8 | echo "You need to pass the \$GIT_EMAIL variable to the container for this to work" 9 | exit 10 | fi 11 | 12 | if [ -z "$GIT_NAME" ]; then 13 | echo "You need to pass the \$GIT_NAME variable to the container for this to work" 14 | exit 15 | fi 16 | 17 | ts=$(timestamp) 18 | cd /var/www/html 19 | git add . 20 | git commit -a -m "push from container $ts" 21 | git push 22 | -------------------------------------------------------------------------------- /gcloud_instructions/nfs-shared1-server.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ReplicationController 3 | metadata: 4 | name: nfs-shared1-server 5 | spec: 6 | replicas: 1 7 | selector: 8 | role: nfs-shared1-server 9 | template: 10 | metadata: 11 | labels: 12 | role: nfs-shared1-server 13 | spec: 14 | containers: 15 | - name: nfs-shared1-server 16 | image: gcr.io/google_containers/volume-nfs:0.8 17 | resources: 18 | limits: 19 | cpu: 0.01 20 | ports: 21 | - name: nfs 22 | containerPort: 2049 23 | - name: mountd 24 | containerPort: 20048 25 | - name: rpcbind 26 | containerPort: 111 27 | securityContext: 28 | privileged: true 29 | volumeMounts: 30 | - mountPath: /exports 31 | name: nfs-shared1-200gb 32 | volumes: 33 | - name: nfs-shared1-200gb 34 | persistentVolumeClaim: 35 | claimName: nfs-shared1-200gb -------------------------------------------------------------------------------- /php5.6/scripts/init_git.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # From https://github.com/ngineered/nginx-php-fpm 3 | # Disable Strict Host checking for non interactive git clones 4 | mkdir -p -m 0700 /root/.ssh 5 | echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config 6 | 7 | if [[ "$GIT_USE_SSH" == "1" ]] ; then 8 | echo -e "Host *\n\tUser ${GIT_USERNAME}\n\n" >> /root/.ssh/config 9 | fi 10 | 11 | if [ ! -z "$SSH_KEY" ]; then 12 | echo $SSH_KEY > /root/.ssh/id_rsa.base64 13 | base64 -d /root/.ssh/id_rsa.base64 > /root/.ssh/id_rsa 14 | chmod 600 /root/.ssh/id_rsa 15 | fi 16 | 17 | # Setup git variables 18 | if [ ! -z "$GIT_EMAIL" ]; then 19 | git config --global user.email "$GIT_EMAIL" 20 | fi 21 | if [ ! -z "$GIT_NAME" ]; then 22 | git config --global user.name "$GIT_NAME" 23 | git config --global push.default simple 24 | fi 25 | 26 | # Dont pull code down if the .git folder exists 27 | if [ ! -d "/var/www/html/.git" ]; then 28 | # Pull down code from git for our site! 29 | if [ ! -z "$GIT_REPO" ]; then 30 | # Remove the test index file 31 | rm -Rf /var/www/html/* 32 | GIT_COMMAND='git clone ' 33 | if [ ! -z "$GIT_BRANCH" ]; then 34 | GIT_COMMAND=${GIT_COMMAND}" -b ${GIT_BRANCH}" 35 | fi 36 | 37 | if [ -z "$GIT_USERNAME" ] && [ -z "$GIT_PERSONAL_TOKEN" ]; then 38 | GIT_COMMAND=${GIT_COMMAND}" ${GIT_REPO}" 39 | else 40 | if [[ "$GIT_USE_SSH" == "1" ]]; then 41 | GIT_COMMAND=${GIT_COMMAND}" ${GIT_REPO}" 42 | else 43 | GIT_COMMAND=${GIT_COMMAND}" https://${GIT_USERNAME}:${GIT_PERSONAL_TOKEN}@${GIT_REPO}" 44 | fi 45 | fi 46 | ${GIT_COMMAND} /var/www/html || exit 1 47 | chown -Rf www-data:www-data /var/www/html 48 | fi 49 | fi 50 | 51 | # Run custom scripts 52 | if [[ "$RUN_SCRIPTS" == "1" ]] ; then 53 | if [ -d "/var/www/html/scripts/" ]; then 54 | # make scripts executable incase they aren't 55 | chmod -Rf 750 /var/www/html/scripts/* 56 | # run scripts in number order 57 | for i in `ls /var/www/html/scripts/`; do /var/www/html/scripts/$i ; done 58 | else 59 | echo "Can't find script directory" 60 | fi 61 | fi 62 | -------------------------------------------------------------------------------- /php7.0/scripts/init_git.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # From https://github.com/ngineered/nginx-php-fpm 3 | # Disable Strict Host checking for non interactive git clones 4 | mkdir -p -m 0700 /root/.ssh 5 | echo -e "Host *\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config 6 | 7 | if [[ "$GIT_USE_SSH" == "1" ]] ; then 8 | echo -e "Host *\n\tUser ${GIT_USERNAME}\n\n" >> /root/.ssh/config 9 | fi 10 | 11 | if [ ! -z "$SSH_KEY" ]; then 12 | echo $SSH_KEY > /root/.ssh/id_rsa.base64 13 | base64 -d /root/.ssh/id_rsa.base64 > /root/.ssh/id_rsa 14 | chmod 600 /root/.ssh/id_rsa 15 | fi 16 | 17 | # Setup git variables 18 | if [ ! -z "$GIT_EMAIL" ]; then 19 | git config --global user.email "$GIT_EMAIL" 20 | fi 21 | if [ ! -z "$GIT_NAME" ]; then 22 | git config --global user.name "$GIT_NAME" 23 | git config --global push.default simple 24 | fi 25 | 26 | # Dont pull code down if the .git folder exists 27 | if [ ! -d "/var/www/html/.git" ]; then 28 | # Pull down code from git for our site! 29 | if [ ! -z "$GIT_REPO" ]; then 30 | # Remove the test index file 31 | rm -Rf /var/www/html/* 32 | GIT_COMMAND='git clone ' 33 | if [ ! -z "$GIT_BRANCH" ]; then 34 | GIT_COMMAND=${GIT_COMMAND}" -b ${GIT_BRANCH}" 35 | fi 36 | 37 | if [ -z "$GIT_USERNAME" ] && [ -z "$GIT_PERSONAL_TOKEN" ]; then 38 | GIT_COMMAND=${GIT_COMMAND}" ${GIT_REPO}" 39 | else 40 | if [[ "$GIT_USE_SSH" == "1" ]]; then 41 | GIT_COMMAND=${GIT_COMMAND}" ${GIT_REPO}" 42 | else 43 | GIT_COMMAND=${GIT_COMMAND}" https://${GIT_USERNAME}:${GIT_PERSONAL_TOKEN}@${GIT_REPO}" 44 | fi 45 | fi 46 | ${GIT_COMMAND} /var/www/html || exit 1 47 | chown -Rf www-data:www-data /var/www/html 48 | fi 49 | fi 50 | 51 | # Run custom scripts 52 | if [[ "$RUN_SCRIPTS" == "1" ]] ; then 53 | if [ -d "/var/www/html/scripts/" ]; then 54 | # make scripts executable incase they aren't 55 | chmod -Rf 750 /var/www/html/scripts/* 56 | # run scripts in number order 57 | for i in `ls /var/www/html/scripts/`; do /var/www/html/scripts/$i ; done 58 | else 59 | echo "Can't find script directory" 60 | fi 61 | fi 62 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | # Drupal container 2 | 3 | # Tutorials: 4 | # https://cloud.google.com/container-engine/docs/quickstart 5 | # adapted from https://cloud.google.com/container-engine/docs/tutorials/persistent-disk/#wordpress_pod 6 | 7 | # Follow https://developers.google.com/identity/protocols/application-default-credentials to get credentials and store the json file in this folder 8 | 9 | # Set environment variable to this set of creds 10 | export GOOGLE_APPLICATION_CREDENTIALS=DrupalContainerEngine-f8ef8a6dc869.json 11 | 12 | # Update gcloud 13 | gcloud components update 14 | 15 | # install kubernetes command line 16 | gcloud components install kubectl 17 | 18 | # Set to europe for all future commands 19 | gcloud config set compute/zone europe-west1-b 20 | 21 | # List properties 22 | gcloud config list 23 | 24 | # Set to our project. Make sure this exists in the UI. 25 | gcloud config set project drupalcontainerengine 26 | 27 | # initialize the cluster 28 | gcloud container clusters create drupalpd \ 29 | --machine-type "f1-micro" \ 30 | --image-type "GCI" \ 31 | --disk-size "100" \ 32 | --scopes "https://www.googleapis.com/auth/compute","https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" --num-nodes 2 \ 33 | --network "default" \ 34 | --enable-cloud-logging \ 35 | --no-enable-cloud-monitoring \ 36 | --enable-autoupgrade 37 | 38 | # Log in to our kubernetes panel 39 | gcloud container clusters get-credentials drupalpd \ 40 | --zone europe-west1-b --project drupalcontainerengine 41 | 42 | kubectl proxy 43 | # Browse to http://localhost:8001/ui 44 | 45 | # mysql 46 | # Set up a managed mysql instance and import a database into it. Next, copy the nickveenhofbe folder and modify the information in pods.yaml to match your setup. 47 | 48 | # Create NFS Server PV & Claim 49 | kubectl create -f nfs-shared1-pv.yaml 50 | 51 | # Create NFS Server 52 | kubectl create -f nfs-shared1-server.yaml 53 | 54 | # Create a folder for your site 55 | kubectl exec -it nfs-shared1-server-rxlfk mkdir /exports/nickveenhofbe 56 | 57 | # Create NFS Service 58 | kubectl create -f nfs-shared1-service.yaml 59 | 60 | # Get the IP Address for our NFS Shared1 server 61 | kubectl describe service nfs-shared1-server 62 | 63 | # Replace IP address in nickveenhofbe/nfs-pv.yaml 64 | # And Create NFS folder volume to mount for our site 65 | kubectl create -f nickveenhofbe/nfs-pv.yaml 66 | 67 | # Claim this NFS folder volume 68 | kubectl create -f nickveenhofbe/nfs-pv-claim.yaml 69 | 70 | # Start the pods (2 of them) 71 | kubectl create -f nickveenhofbe/pods.yaml 72 | 73 | # Update the Drupal pod 74 | kubectl replace -f nickveenhofbe/pods.yaml 75 | 76 | # Create drupal service 77 | kubectl create -f nickveenhofbe/lb.yaml 78 | 79 | # verify that it points to defined endpoints (eg, ip's) 80 | kubectl describe service nickveenhofbe 81 | 82 | # Get our properties in order to visit our site. Wait till it mentions a property like: "LoadBalancer Ingress". It might take a while before the load balancer is created. 83 | kubectl describe service nickveenhofbe 84 | 85 | # Visit the site on the Public IP that is found in the load balancer 86 | # and behold the beauty of your own HA site. 87 | 88 | # Caveats & TODOs 89 | # It does not properly use the NFS voluem yet to share files for sites/default/files so file uploads will only be seen in 1 of the 2 pods. -------------------------------------------------------------------------------- /gcloud_instructions/nickveenhofbe/pods.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | creationTimestamp: null 5 | name: nickveenhofbe 6 | labels: 7 | site: nickveenhofbe 8 | spec: 9 | replicas: 2 10 | strategy: 11 | type: Recreate 12 | template: 13 | metadata: 14 | creationTimestamp: null 15 | labels: 16 | site: nickveenhofbe 17 | service: nickveenhofbe 18 | spec: 19 | containers: 20 | - image: nickveenhof/drupal-docker-with-volume:5.6 21 | name: php 22 | resources: 23 | limits: 24 | cpu: 0.01 25 | env: 26 | - name: PHP_HOST_NAME 27 | value: localhost:8000 28 | - name: PHP_SENDMAIL_PATH 29 | value: /usr/sbin/sendmail -t -i -S mailhog:1025 30 | - name: PHP_SITE_NAME 31 | value: nick 32 | - name: GIT_EMAIL 33 | value: nick.veenhof@gmail.com 34 | - name: GIT_NAME 35 | value: 'Nick Veenhof' 36 | - name: GIT_USERNAME 37 | value: 'nick_vh' 38 | - name: ERRORS 39 | value: '0' 40 | - name: GIT_REPO 41 | value: 'gitlab.com/nick_vh/nickveenhof.be.git' 42 | - name: GIT_PERSONAL_TOKEN 43 | valueFrom: 44 | secretKeyRef: 45 | name: gitlab 46 | key: gitlab_token 47 | # These secrets are required to start the pod. 48 | # [START cloudsql_secrets] 49 | # Connect to the SQL proxy over the local network on a fixed port. 50 | # Insert the port number used by your database. 51 | - name: DB_HOST 52 | value: 127.0.0.1:3306 53 | - name: DB_NAME 54 | # Connect to the SQL proxy over the local network on a fixed port. 55 | # Insert the port number used by your database. 56 | value: drupal 57 | - name: DB_PASSWORD 58 | valueFrom: 59 | secretKeyRef: 60 | name: cloudsql 61 | key: password 62 | - name: DB_USER 63 | valueFrom: 64 | secretKeyRef: 65 | name: cloudsql 66 | key: username 67 | volumeMounts: 68 | - mountPath: /var/www/html 69 | name: site-files 70 | - mountPath: /mnt/nfs 71 | name: nfs 72 | - image: wodby/drupal-nginx:7-1.10 73 | resources: 74 | limits: 75 | cpu: 0.005 76 | env: 77 | - name: DRUPAL_VERSION 78 | value: "8" 79 | - name: NGINX_SERVER_NAME 80 | value: localhost 81 | - name: NGINX_UPSTREAM_NAME 82 | value: php 83 | - name: NGINX_BACKEND_HOST 84 | value: localhost 85 | name: nginx 86 | ports: 87 | - containerPort: 80 88 | volumeMounts: 89 | - mountPath: /var/www/html 90 | name: site-files 91 | readOnly: true 92 | - mountPath: /mnt/nfs 93 | name: nfs 94 | readOnly: true 95 | # Change [INSTANCE_CONNECTION_NAME] here to include your GCP 96 | # project, the region of your Cloud SQL instance and the name 97 | # of your Cloud SQL instance. The format is 98 | # $PROJECT:$REGION:$INSTANCE 99 | # Insert the port number used by your database. 100 | # [START proxy_container] 101 | - image: b.gcr.io/cloudsql-docker/gce-proxy:1.05 102 | resources: 103 | limits: 104 | cpu: 0.005 105 | name: cloudsql-proxy 106 | command: ["/cloud_sql_proxy", "--dir=/cloudsql", 107 | "-instances=drupalcontainerengine:europe-west1:drupal=tcp:3306", 108 | "-credential_file=/secrets/cloudsql/credentials.json"] 109 | volumeMounts: 110 | - name: cloudsql-oauth-credentials 111 | mountPath: /secrets/cloudsql 112 | readOnly: true 113 | - name: ssl-certs 114 | mountPath: /etc/ssl/certs 115 | - name: cloudsql 116 | mountPath: /cloudsql 117 | volumes: 118 | - name: site-files 119 | emptyDir: {} 120 | - name: nfs 121 | persistentVolumeClaim: 122 | claimName: nvbenfs 123 | - name: cloudsql-oauth-credentials 124 | secret: 125 | secretName: cloudsql-oauth-credentials 126 | - name: ssl-certs 127 | hostPath: 128 | path: /etc/ssl/certs 129 | - name: cloudsql 130 | emptyDir: --------------------------------------------------------------------------------