Kojicomics


Configurando mi servidor web

Por Rubén Santos, el

Tras varios meses probando distintos generadores de blogs estáticos, por fin he encontrado el que mejor se adapta a mis necesidades... POSIX + AWK!! 😝

Pero este es un tema que trataré a fondo más adelante, de lo que quiero hablar hoy es de la configuración que utilizo en mi VPS para hacer los despliegues de forma cómoda.

Mi objetivo era crear un entorno simple, con las menores dependencias posibles, que me permitiese desplegar y servir mi sitio web estático directamente desde el entorno de desarrollo.

El sistema consiste en dos programas, que ofrecen las siguientes características:

Git

h2o

¡Comencemos!

Sistema Operativo

Hasta ahora estaba acostumbrado a montar mis servidores bajo Debian, pero tras un año utilizando Gentoo en mi escritorio he decidido llevar el maravilloso sistema de ports a mis servidores.. Y qué mejor opción que el flamante FreeBSD!!

En realidad no tenía opción, porque los cabrones de DigitalOcean todavía no le dan soporte a OpenBSD 😔

La versión que he escogido es la imagen FreeBSD 11.0 de DigitalOcean.

Su uso no puede ser más sencillo: enlazar la llave pública de tu equipo y conectarte por ssh con el usuario freebsd.

Los pasos de configuración son comunes para cualquier sistema *nix

GIT

El primer paso es instalar git, disponible en devel/git:

root # cd /usr/ports/devel/git
root # make install clean

A continuación creamos un usuario para facilitar la gestión de permisos. Le llamamos git, y especificamos su home en el directorio /var/lib/git.

Iniciamos sesión con el nuevo usuario y creamos el fichero que almacenará la llave pública para acceder por ssh. La copiamos desde el equipo de desarrollo.

git@servidor$ mkdir ~/.ssh
git@servidor$ chmod 700 ~/.ssh
git@servidor$ touch ~/.ssh/authorized_keys
git@servidor$ chmod 600 ~/.ssh/authorized_keys

user@local$ cat ~/.ssh/id_rsa.pub | git@server.domain "cat >> ~/.ssh/authorized_keys"

Ahora podremos crear repositorios fácilmente dentro de /var/lib/git/ con el comando: git init --bare project.git.

Desde el equipo de desarrollo podremos clonar el nuevo repositorio o subir uno existente:

# Nuevo repositorio
git clone git@server.domain:project.git
# Migrar repositorio existente
cd project
git remote add origin git@server.domain:project.git
git push -u origin master

Servidor web

El primer paso es instalar el servidor web h2o, disponible en www/h2o:

root # cd /usr/ports/www/h2o
root # make install clean

Seguidamente creamos el directorio del servidor web y le asignamos permisos para www:www:

root # mkdir /var/lib/www
root # chown -R www:www /var/lib/www
root # chmod -R 755 /var/lib/www

A continuación creamos el directorio que almacenará el sitio web y le asignamos al usuario git como propietario:

root # mkdir -p /var/lib/www/site/public
root # chown -R git:www /var/lib/www/site
root # chmod -R 775 /var/lib/www/site

Creamos un fichero de configuración en /var/lib/www/config.yml y definimos el host de nuestro sitio web:

listen:
  port: 80
user: www
hosts:
  "server.domain":
    paths:
      /:
        file.dir: /var/lib/www/site/public
        access-log: /var/lib/www/site/access-log
error-log: /var/lib/www/site/error-log
pid-file: /var/lib/www/site/h2o.pid

Para ejecutar manualmente el servidor, ejecutamos el comando:

root # h2o -m daemon -c /var/lib/www/config.yml

Para detener manualmente el servidor, ejecutamos el comando:

root # kill -TERM `cat /var/lib/www/h2o.pid`

En FreeBSD podemos automatizarlo activando el servicio de h2o en el fichero /etc/rc.conf:

h2o_enable="YES"
h2o_config="/var/lib/www/config.yml"

Funcionamiento del repositorio

Generalmente, los generadores des webs estáticas se componen de dos partes:

Para aprovechar al máximo las ventajas de Git crearemos una rama para cada una de estas partes del sitio.

El diagrama básico de funcionamiento sería algo así:

diagrama

El proceso completo para manejar esta situación sería el siguiente:

  1. Persistir los cambios de las fuentes originales dentro de la rama master.
  2. Guardar los cambios que todavía no queremos persistir:
    git stash save
    
  3. Compilar las fuentes en la carpeta output
  4. Guardar el hash de los cambios en una variable:
    REV=$(git rev-parse HEAD)
    
  5. Cambiar a la rama output (si no existe crear con git checkout -b output):
    git checkout output
    
  6. Eliminar todos los ficheros del árbol:
    git rm -rf .
    
  7. Aplicar el .gitignore de la rama master:
    git checkout master -- .gitignore
    
  8. Extraer el contenido de output/ y eliminar su directorio:
    mv output/* . && rm -rf output/
    
  9. Añadir y persistir los cambios:
    git add . && git commit -m "deployed $(REV)"
    
  10. Subir todos los cambios al servidor:
    git push --all
    
  11. Recuperar los cambios no persistidos en master:
    git checkout master
    git stash pop

Para simplificar el proceso, he creado un Makefile con la regla deploy que automatiza todos los pasos del despliegue.

Despliegue automático

El siguiente paso es configurar el servidor para que mueva el contenido de la rama output al directorio configurado para h2o.

Entramos en el repositorio git del servidor y dentro de la carpeta hooks/ creamos el fichero post-receive con el siguiente contenido:

#!/bin/sh

while read oldrev newrev refname; do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "output" == "$branch"]; then
        GIT_WORK_TREE="/var/lib/www/site/" git checkout -f output
    fi
done

Este script se lanzará cada vez que el servidor remoto reciba un push. Básicamente comprueba que la rama modificada sea output y ejecuta un checkout de su contenido dentro del directorio definido en GIT_WORK_TREE.

Conclusión

Una vez configurado el servidor, el proceso de despliegue no puede ser más sencillo:

Realizamos los cambios en las fuentes, los persistimos y ejecutamos make deploy. Automáticamente compilará las fuentes, separará el contenido de la carpeta output/ en otra rama y copiará su contenido al directorio configurado para h2o.

Fuentes