Tenemos que tener en cuenta que no vamos a tener ni el vendor ni los contrib de modules o themes en el repositorio por lo que vamos a usar composer. En cada deploy se va a instalar lo que tengamos en composer.json y en caso de tener parches definidos en composer, aplicarlos.
Nuestra primera tarea es instalar composer en nuestro alojamiento y para eso accedemos con las credenciales ssh que nos dan y creamos un directorio llamado bin donde vamos a instalar las aplicaciones que necesitemos.
$ mkdir bin
Voy a asumir ciertas cosas como que hemos elegido php 8.1 para nuestro alojamiento. Dicho esto procedemos a descargarnos e installar composer en nuestro hosting.
$ curl -sS https://getcomposer.org/installer | php -- --install-dir=./bin --filename=composer
Uno de los problemas con el que nos topamos a la hora de implementar este sistema de integración continua es que el deploy (lo veremos un poco más adelante) va a eliminar todo el documment root y lo va a crear de nuevo clonando la rama de github que nosotros le indiquemos.
Lo ideal para realizar esto sería hacerlo en un directorio fuera del document root usando un timestamp como nombre y una vez completado el deploy sin errores crear un symlink al document root. Para esta ocasión no nos vamos a complicar mucho y lo vamos a realizar todo sobre el document root directamente.
El siguiente problema es el directorio de ficheros públicos de Drupal. Por lo comentado anteriormente, tiene que quedar fuera del document root para evitar que se borre en cada deploy. En el fichero settings que estemos usando es conveniente comentar o eliminar la configuración del public files que viene.
$ mkdir -p shared/example.com/files
Para terminar con la preparación de Drupal, esta parte es opcional y por eso no la voy a explicar aquí, configuramos el sites.php para poder tener nuestros directorios de configuración de drupal separados para poder trabajar en local, desarrollo y prod. Hay mas configuraciones como thrusted hosts, proxies, etc... que tampoco corresponde que se expliquen aquí.
Bien, ya tenemos nuestro código subido a Github y el entorno de hosting preparado para empezar a trabajar.
Lo primero es crear, dentro de nuestro proyecto de Github el siguiente directorio:
$ mkdir -p .github/workflows
Dentro de este directorio el fichero main.yaml (He elegido ese nombre por que coincide con la rama que quiero usar para producción).
name: Deploy to OVHcloud Power
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-20.04
env:
OVH_SSH_HOST: ${{ secrets.OVH_SSH_HOST }}
OVH_SSH_PORT: ${{ secrets.OVH_SSH_PORT }}
OVH_SSH_USERNAME: ${{ secrets.OVH_HOSTING_USER }}
OVH_SSH_PASSWORD: ${{ secrets.OVH_HOSTING_PASSWORD }}
OVH_WEBSITE_URL: ${{ secrets.OVH_WEBSITE_URL }}
DRUPAL_USER: ${{ secrets.DRUPAL_USER }}
steps:
- name: Install prerequisites
run: |
sudo apt-get update
sudo apt-get install -y curl jq sshpass openssh-client
- name: WakeUp website
run: curl --silent --insecure --location --write-out "%{http_code}" -o /dev/null ${OVH_WEBSITE_URL}
- name: Clone over SSH
run: sshpass -p ${OVH_SSH_PASSWORD} ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oLogLevel=quiet ${OVH_SSH_USERNAME}@${OVH_SSH_HOST} -p ${OVH_SSH_PORT} -- 'chmod -R 777 www/sites/ && rm -rf www && git clone '${GITHUB_SERVER_URL}'/'${GITHUB_REPOSITORY}'.git --single-branch --branch '${GITHUB_REF##*/}' www'
- name: Composer install
run: sshpass -p ${OVH_SSH_PASSWORD} ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oLogLevel=quiet ${OVH_SSH_USERNAME}@${OVH_SSH_HOST} -p ${OVH_SSH_PORT} -- 'php ./bin/composer install -d www'
- name: Create sym links
run: sshpass -p ${OVH_SSH_PASSWORD} ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oLogLevel=quiet ${OVH_SSH_USERNAME}@${OVH_SSH_HOST} -p ${OVH_SSH_PORT} -- 'cd www/sites/gelr.es && ln -s ../../../shared/gelr.es/files files'
- name: Drupal credentials
run: sshpass -p ${OVH_SSH_PASSWORD} ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oLogLevel=quiet ${OVH_SSH_USERNAME}@${OVH_SSH_HOST} -p ${OVH_SSH_PORT} -- 'php bin/envs.php www/sites/gelr.es/settings.php'
- name: Rebuild drupal
run: sshpass -p ${OVH_SSH_PASSWORD} ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oLogLevel=quiet ${OVH_SSH_USERNAME}@${OVH_SSH_HOST} -p ${OVH_SSH_PORT} -- 'cd www/sites/gelr.es && ../../vendor/bin/drush rebuild'
- name: WakeUp website
run: curl --silent --fail --insecure --location --write-out "%{http_code}" -o /dev/null ${OVH_WEBSITE_URL}
Si tenemos que resumir lo que hace este fichero en unas pocas palabras podríamos decir que Github crea un container de docker con linux y alguna aplicacion para poder conectarse a nuestro hosting y ejecutar comandos sobre el:
Clone Over SSH
Realiza dos acciones principales. Cambiar los permisos del directorio site. Esto es por que drupal, de forma automática y así está definido en su settings cambia los permisos cuando accedemos a el y quita el permiso de escritura (lo mas normal del mundo). Los siguiente es borrar el document root y por último clonar nuestra rama en el nuevo document root.
Composer install
Ya habíamos instalado nuestro composer en el hosting. En este paso del deploy se ejecuta el install para que genere el vendor y los contrib que estamos usando y tenemos definidos en nuestro composer.json|lock.
php ./bin/composer install -d www
Create Sym links
Como sacamos nuestro directorio de files public de Drupal fuera del document root necesitamos enlazar el files dentro del document root a nuestro shared fuera del document root. La mejor forma que he encontrado es hacerlo de forma relativa al document root por eso que lo haga de esta manera:
cd www/sites/example.com && ln -s ../../../shared/example.com/files files
Drupal credentials
Al tener el proyecto en un repositorio público y las bases de datos de ovh son de acceso público con phpmyadmin. Se usan tokens para las credenciales de base de datos en el settings.php y se reemplazan en este punto del deploy con un script alojado en el servidor.
Rebuild drupal
En este paso simplemente hacemos un rebuild del site drupal para que renere todas las caches y aplique bien los cambios que pudieramos haber hecho en templates, css y demás.
WakeUp Website
Por último solo nos queda comprobar que el site está funcionando y no está dando errores tipo 500.
Quizás me dejo por comentar como se crear los secrets en Github. En cualquier, caso dentro de settings del projecto de Github, en security, se pueden crear las secrets y variables.
Con todo esto, ya solo tenemos que hacer nuestros push a la rama y automáticamente nos hará el deploy a nuestro hosting.