Bad Daemons

Actualizar el contenido de una web mediante un hook de git

git mola mucho. Tiene mucha más potencia que la de compartir archivos, y lo de ahora apenas será rascar la superficie. Hoy veremos los llamados hooks de git, uno en concreto llamado post-update.

Primero un resumen, que son los hooks de git? Son scripts que se ejecutan en función a eventos. Unos ejemplos son el pre-commit, pre-receive, post-commit o post-update. Los nombres son bastante lógicos, no tiene sentido dedicarle más tiempo.

Entonces, la ideal de manual es enseñar cómo actualizar el contenido de una web, por ejemplo, haciendo solamente un push a un repositorio git. El escenario es el siguiente:

  • Repositorio git (llamado ~/web en el ejemplo)
  • Directorio de la web (llamado /var/www/web)
  • Cliente

Por lo tanto, desde el cliente se pusheará al repositorio git, y este automaticamente se irá al directorio de la web y hará un git pull. Todo esto sin tener que lidiar con ssh, ftp ni nada similar. Al lío.

En el servidor se creará un usuario llamado git, en el home de este se creará el repositorio, luego se pondrá la clave ssh del cliente en authorized_keys (para no tener que estar poniendo la contraseña del usuario git del servidor) y luego se creará el hook.

# Desde el servidor
$ su -c "adduser git"
$ su -c "su git"
$ cd ~
$ git init --bare web
# Desde el cliente
$ cat ~/.ssh/id_rsa.pub
# lo que devuelva se copia en una sola linea en el siguiente fichero del servidor
$ nano ~/.ssh/authorized_keys
# creamos el hook
$ nano ~/web/hooks/post-update
# y insertamos...

#!/bin/bash
cd /var/www/web
umask 0022
echo "Updating remote folder..."
env -i git pull 1> /dev/null

El anterior script es bastante chustero, pero hace su función. Lo suyo seria usar las variables GIT_REPO y GIT_WORKDIR, pero no tenia ganas y para lo poco que lo uso me vale. Lo que hace, por cierto, es entrar en el directorio de la web, establecer una máscara que se adecúe a los permisos que hay, informar de que se procede a actualizar la rama y a ejecutar un pull del repositorio sin variables de entorno (como las ya mencionadas GIT_REPO y GIT_WORKDIR).

Se ejecuta chmod +x post_update y si los permisos son correctos, ese repositorio se actualizará cada vez que se haga un push.