Menu
Foto por: Tim Mossholder

Despliegue continuo de este blog con Gitlab

Author image

Escrito por

Álex Martín

Siguiendo con el post anterior sobre “cómo construimos nuestro blog con Nuxt” hoy nos toca explicar como agilizamos la subida de cada post.

Si leíste el anterior post, recordarás que todos nuestros artículos están escritos en Markdown y que lo subimos a una carpeta /contents/blog.

Teniendo esto como base, pensamos que la mejor forma de optimizar nuestras subidas sería mediante algún método de “CI/CD” que actualizara nuestro blog cada vez que subamos cambios sobre esa carpeta. Para aislarlo del código del blo, creamos un repositorio sólo para el contenido y configuramos gitlab para que cualquier cambio realizado en la rama master fuese desplegado en nuestro servidor de codetakers.

Configuración

Gitlab ofrece un sistema de CI/CD desde su versión gratuita que es realmente fácil de configurar y ejecutar. El fichero principal para esta configuración es .gitlab-ci.yml que debe ubicarse en el raiz del repositorio.

Veamos la estructura de nuestro .gitlab-ci.yml:

deploy:
  image: alpine
  stage: deploy
  only:
    - master
  script:
    - apk add --no-cache rsync openssh
    - mkdir -p ~/.ssh
    - echo "$CODETAKERS_SSH_PRIVATE_KEY" >> ~/.ssh/id_dsa
    - chmod 600 ~/.ssh/id_dsa
    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
    - rsync -rav --delete *.md $CODETAKERS_USER_HOST:$CODETAKERS_SERVER_PATH/contents/blog
    - rsync -rav --delete images $CODETAKERS_USER_HOST:$CODETAKERS_SERVER_PATH/contents/blog
    - ssh -t $CODETAKERS_USER_HOST "cd $CODETAKERS_SERVER_PATH&&yarn&&yarn build&&pm2 start"

El el código de arriba establecemos un Job llamado deploy que usa una imagen docker alpine (imagen reducida de linux) .

Por defecto Gitlab define 3 stages, que son:

  • build
  • test
  • deploy

Por ello, podemos crear distintos jobs en distintas stages. Cabe decir, que si ponemos dos trabajos en un mismo stage, se ejecutará de forma paralela.

En nuestro código seleccionamos la fase deploy, aunque nos hubiera bastado con cualquiera de las otras dos por defecto.

El siguiente punto es only: master esto nos indica que el trabajo se ejecutará sólo cuando hagamos un push a master y no en otras ramas del repositorio.

Por último tenemos todas las tareas que ejecuta la instancia de la imagen alpine. Veamos una por una:

apk add --no-cache rsync openssh

Añadimos los packages rsync y openssh. Rsync es una herramienta que nos permitirá realizar subidas de ficheros a otros servidores. OpenSSH nos permitirá conectarnos a otros equipos mediante el protocolo SSH.

mkdir -p ~/.ssh

Creamos una carpeta .ssh donde alojaremos nuestras claves públicas y privadas para comunicarnos con el servidor.

echo "$CODETAKERS_SSH_PRIVATE_KEY" >> ~/.ssh/id_dsa

Para lograr que nuestra instancia de docker se pueda conectar con nuestro servidor remoto debemos generar nuestras claves y preparar el servidor para aceptar peticiones desde la instancia de docker. Por ello, nos conectaremos a nuestro servidor y realizaremos las siguientes tareas:

ssh-keygen -t dsa
cd .ssh
mv id_dsa.pub authorized_keys
cat id_dsa && rm id_dsa

En el código de arriba generamos un par de claves SSH. Añadimos la clave pública como clave con acceso autorizado, mostramos por mantalla la clave privada, y la borramos.

En ese momento tendremos que copiar el contenido de id_rsa y añadirlo como variable de entorno en el apartado Settings > CI / CD > Variables como CODETAKERS_SSH_PRIVATE_KEY

Una vez hecho esto, es cuando podemos ver que la instancia usará la clave privada del par que tenemos como autorizada en nuestro servidor.

chmod 600 ~/.ssh/id_dsa

Cambiamos los permisos de id_rsa para que sólo su propietario pueda realizar cambios.

echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config

Evitamos que el servidor pregunte si queremos añadir el fingerprint al fichero know_hosts haciéndolo por defecto.

rsync -rav --delete *.md $CODETAKERS_USER_HOST:$CODETAKERS_SERVER_PATH/contents/blog**

En este comando usamos Rsync para conectarnos al servidor y subir todos los ficheros con extensión md.

Previamente tendremos que configurar, al igual que hicimos con la clave privada, los parámetros:

  • $CODETAKERS_USER_HOST: Usuario con el que creamos las claves públicas y con el que subiremos los contenidos.
  • $CODETAKERS_SERVER_PATH: Ubicación del directorio raíz donde colocaremos nuestros contenidos.
rsync -rav --delete images $CODETAKERS_USER_HOST:$CODETAKERS_SERVER_PATH/contents/blog**

Aquí copiamos las imágenes contenidas en en el directorio images

ssh -t $CODETAKERS_USER_HOST "cd $CODETAKERS_SERVER_PATH&&yarn&&yarn build&&pm2 start"**

Como usamos SSR, debemos generar el código para las nuevas páginas que hemos creado, por ello debemos acceder al directorio del proyecto, lo reconstruimos con yarn build y reiniciamos el servidor node.

Conclusiones

Como habrás podido comprobar, Gitlab nos pone muy fácil realizar despliegues. Más adelante os contaremos cómo sacarle más jugo a esta magnífica herramienta.

Por otro lado, si ves erratas o quieres añadir cualquier puntualización a nuestros artículos, el repositorio del blog está abierto a cualquier pull request :)

Referencias

https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories-on-a-vps

https://www.shellhacks.com/disable-ssh-host-key-checking/

https://gitlab.com/alexdw/codetakers_blog