Simple deploy con Git

  • authorJordi Touza Bonnin
  • 13 de junio de 2021

Vamos a crear un repositorio tipo bare en nuestro servidor de producción que contiene las instrucciones para actualizar el proyecto. De esta forma con los propios comandos de GIT podremos hacer deploy en el servidor sin tener que conectarnos a él directamente.

Requisitos

  • Servidor unix con acceso SSH usando llaves públicas/privadas
  • Repositorio git (en Github, Gitlab...)

Tanto si usas master como rama de producción o cualquier otra, el proceso es el mismo. Para evitar confusiones con nombres raros uso a modo de ejemplo mi propio sitio web.

1. Crear la carpeta de deploy

Accede a tu servidor y crea una carpeta donde se ejecutará el proyecto. Generalmente sigo así:

cd /var/www
mkdir www.backtheweb.com

Nota: Si ya estas usando esa carpeta con GIT, borra el directorio ~.git~

2. Añadir un repositio brare en el servidor

Ahora vamos a crear un repositorio bare el cual básicamente tiene el contenido del proyecto GIT sin la copia de trabajo. Puedes llamarlo como quieras, pero por nomenclatura te recomiendo dejar el .git en el nombre.

Ahora sitúate en la home del usuario:

cd ~
git clone --bare git@gitlab.com:backtheweb/backtheweb.git 

3. post-receive hook script

Cuando hagas un push en tu máquina local el hook se encargará de mover los ficheros a la carpeta destino.

Edita o crea el fichero post-receive.

cd  ~/backtheweb.git/hooks
nano post-receive

Ahora copia este contenido al fichero. Personalízalo con el nombre de tu proyecto, tus rutas y la rama que quieres usar.

#!/bin/bash
TARGET="/var/www/www.backtheweb.com"
GIT_DIR="/root/backtheweb.git"
BRANCH="master"

while read oldrev newrev ref
do
    # only checking out the master (or whatever branch you would like to deploy)
    if [ "$ref" = "refs/heads/$BRANCH" ];
    then
        echo "Ref $ref received. Deploying ${BRANCH} branch to production..."

        git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
            
    else
        echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server."
    fi
done

No olvides que este fichero deberá tener permisos de execución

chmod +x post-receive

4. Un nuevo remote-repository en tu local

En tu máquina local dirígete a la raíz de tu proyecto GIT.

cd ~/projects/www.backtheweb.com/
git remote add prod username@backtheweb.com:backtheweb.git

5. Push al servidor de producción

Ahora ya puedes hacer el deploy con push de tu rama master. ¿Cómo?

git push production master

Fíjate que estás haciendo push en el servidor de producción no al servidor donde tiene el proyecto GIT (github, gitlab...)

6. Consejo extra

Si hasta aquí todo ha ido bien, es momento para mejorar el post-receive. Aquí podemos ejecutar todas las tareas que queremos después de volcar el código como por ejemplo vaciar la caché.

En mi caso, para mi proyecto laravel me interesa hacer lo siguiente:

  1. Poner la web en modo mantenimiento
  2. Tras mover los ficheros, instalar las dependencias fijadas en el composer.lock
  3. Actualizar la base de datos
  4. Optimizar los ficheros configuración, routes, vaciar caché...
  5. Levantar de nuevo el sitio
#!/bin/bash
TARGET="/var/www/www.backtheweb.com"
GIT_DIR="/username/backtheweb.git"
BRANCH="master"

while read oldrev newrev ref
do
    # only checking out the master (or whatever branch you would like to deploy)
    if [ "$ref" = "refs/heads/$BRANCH" ];
    then
        echo "Ref $ref received. Deploying ${BRANCH} branch to production..."
        
## Maintenance mode on
php ${TARGET}/artisan down 2> /dev/null
git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
composer install -d $TARGET --no-progress --no-interaction --prefer-dist --no-suggest

## laravel
php ${TARGET}/artisan optimize
php ${TARGET}/artisan migrate
php ${TARGET}/artisan up 2> /dev/null
        
    else
        echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server."
    fi
done

7. Bonus

Para probar el hook, necesitamos hacer un commit. Para no ensuciar el código con commits innecesarios, podemos hacer un commit vacío.

$ git commit --allow-empty -m "Trigger hook"

Deja tu comentario