Mon architecture jekyll est composée d’un repository git, hébergé sur mon serveur Arch Linux, d’un virtual host nginx sur la même machine et du hook git qui fait le lien.

Je pars du principe que le repository a déjà été créé sur le serveur gogs.

Les prérequis à installer sur chaque ordinateur (le poste développeur, le serveur) sont ruby et bundler :

$ sudo pacman -S ruby ruby-bundler

Je vous laisse ensuite consulter les quelques screencast qui suivent :

Creation du projet sur le poste développeur

  • Je clone le repository git (vide), depuis le serveur Git : git clone gogs@burdet.ch:jfburdet/blog.git
  • Utilisant le gestionnaire de dépendance/package Ruby Bundler (Jekyll est écrit en Ruby), j’initialise son l’environement via bundle init puis édite le Gemfile pour indiquer que le projet à besoin de la gem ‘jekyll’ et finalement lui dit de constuire le projet en prenant comme chemin d’installation un répertoire spécifique de notre arborescence : bundle install --path _vendor/bundle
  • Il faut noter que le bundle install initial est relativement lent, car il faut aller télécharger les dépendances, les suivants seront presques instantannés. C’est ce que je montre en relançant une seconde fois la commande dans le screencast : elle s’exécute rapidement.
  • Jekyll étant maintenant installé dans notre environement bundler, je l’invoque pour créer un nouveau site jekyll dans le répertoire courant. Normalement, il s’attend à un répertoire vide, mais comme nous avons déjà des fichiers de configuration Git et Bundler, nous devons utiliser l’option --force : bundle exec jekyll new --force .
  • Finalement, je configure Git : J’exclu _vendor/bundle car il s’agit d’un répertoire d’artifacts (de données générées) spécifique à chaque instance où tourne jekyll. Je vérifie que ce qui est à comiter correspond bien à des fichiers de données, puis je commit.

Configuration de base Jekyll

  • On s’assure que l’url effective sur lequel le serveur sera hosté, en l’occurence https://blog.burdet.ch correspond à la configuration Nginx
root@orion ~# cat /etc/nginx/servers-enabled/blog.burdet.ch.conf
server {
  listen              80;
  server_name         blog.burdet.ch;

  location '/.well-known/acme-challenge' {
  default_type "text/plain";
    alias        /tmp/letsencrypt-auto;
  }

  location / {
    return              301 https://$server_name$request_uri;
  }
}

server {
        listen 443 ssl;
        server_name blog.burdet.ch;
        root /srv/http/blog.burdet.ch/_site;

        ssl_certificate /etc/letsencrypt.sh/certs/burdet.ch/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt.sh/certs/burdet.ch/privkey.pem;

        include ssl.conf;

        access_log /var/log/nginx/blog.burdet.ch_access.log;
        error_log /var/log/nginx/blog.burdet.ch_error.log debug;

        try_files $uri $uri.html $uri/ =404;

}

Configuration côté serveur

  • On créé le répertoire qui va venir héberger les fichiers côté serveur.
  • Comme le build sera lancé par un hook git sur le serveur [Gogs], on affecte les permissions de ce même user à ce répertoire
  • Sous l’identitié de gogs, on y clone le répertoire, via le ‘protocole’ git fichier.
  • Avec la command umask -S on vérifie que les fichiers généré seront bien lisible par le processus du serveur web (le user http), ce qui est le cas, avec la permission o=rx
  • On configure via la console gogs le hooks git post-receive
#!/usr/bin/bash

unset GIT_DIR

while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "master" == "$branch" ]; then
        echo Push received for branch 'master' : publishing
        cd /srv/http/blog.burdet.ch
        git fetch
        git reset --hard origin/master
        bundle install
        bundle exec jekyll build
    fi
done

A noter le unset GIT_DIR qui est affecté par git pour tous les hooks, qui indique le chemin original. Effacer cette variable permet de s’assurer que la commande git fonctionne bien dans le répertoire courant et non sur le répertoire original qu’on ne veut pas toucher.

A partir de ce moment, un push sur le serveur git va déployer automatiquement la branche ‘master’ dans /srv/http/blog.burdet.ch/_site et sera servie par Nginx. C’est ce qui est illustré dans le dernier screen cast.

Premier deploy automatique

On voit bien l’effet du git push qui déclenche le hook, qui va builder le site et le publier. On note que le screen cast montre bien que le premier push est relativement lent, car c’est la première exécution de la commande bundle install, les suivantes seront presques instantanés.

Mon blog personnel https://blog.burdet.ch se publie donc automatiquement à chaque push de la branche master. Cela me permet de travailler sur des modifications sur la branches develop, tout en pouvant aller faire des corrections sur des articles déjà publiés directement dans master … ceci grace à la magie de Git.

(Note octobre 2016 : Le blog se publie dorénavant via Jenkins, qui un serveur d’intégration continue)