Tarte à la framboise #5 - Feuille de menthe pour le style avec jekyll

12 May 2021

Même si cet article est le 5e de ma série sur les usages du Raspberry Pi, la raison première pour laquelle je me suis intéressé à ces nano-ordinateurs était de pouvoir auto-héberger mon blog chez moi, avec une consommation électrique la plus faible possible tout en laissant l'ordinateur allumé tout le temps.

Auto-hébergement de son blog

Comme expliqué dans la page A propos, j'avais un site Wordpress gratuit sur lequel je publiais mes articles. Dès sa création, j'étais conscient que c'était un peu contradictoire entre le contenu (reprendre la main sur ses données) et le contenant (publier les articles chez un hébergeur privé, pas open-source et tout et tout). Ce n'était que partie remise, jusqu'au moment où j'aurais le temps et la motivation pour m'en occuper.

Certes avec le fait de l'héberger chez moi il y a le risque que ma connexion internet soit pétée pendant X temps, et donc que ce soit inaccessible. Mais comme je pense qu'il y a max 10 personnes qui visitent ce site chaque mois, pas certain que quelqu'un s'en rende compte. Et puis en vrai, ça m'est bien égal.

Créer son blog

Choix du générateur de site statique

Logo de Jekyll

En me documentant un peu sur la façon d'héberger un blog, je suis allé vers la simplicité avec un site statique : léger et simple et maintenir, pas de base de données, pas de gestion/modération de commentaires, une surface d'attaque moindre en cas de tentative de piratage... Deux générateurs de site statique ressortaient : Hugo et jekyll. C'est vers ce dernier que je me suis tourné car sa documentation avait l'air plus accessible et plus détaillée. Oui, je ne voulais pas me prendre la tête et le web c'est pas mon métier.

Installation et configuration sur le Raspberry Pi

jekyll utilise Ruby et la notion de Gem. Son installation est vraiment simple, il suffit de jouer les commandes :

  1. sudo apt-get install ruby-full
  2. sudo gem install bundler
  3. sudo gem install jekyll
  4. bundle install

Vous avez aussi des plugins disponibles pour ajouter des petites fonctionnalités en plus, comme un flux RSS (sudo gem install jekyll-feed) ou une pagination (sudo gem install jekyll-paginate).
Pour la configuration, je vous laisse avec la doc de jekyll qui est très bien faite.

Choix du template

Comme je n'avais pas envie de construire de 0 le site, je suis allé choisir un template qui me plaisait en utilisant les liens fournis sur le site de Jekyll, et c'est tombé sur Hyde (il y a un petit lien Download pour télécharger le contenu sur la gauche si ça vous tente).

Customisation du template

Histoire de ne pas non plus être un copier/coller du template, j'ai légèrement customisé l'apparence avec une meilleure gestion du responsive, un menu de navigation un peu différent, un affichage des articles avec une pagination, d'autres polices d'écriture, une page 404...

Là y'a pas trop de mystère, faut modifier le HTML/CSS du site, et pour ça https://www.w3schools.com est ultra pratique. Sinon faut chercher un peu sur internet, la base quoi.

Génération du site statique

Pour générer le site statique, ça se fait en deux-deux :

  1. Se placer dans le répertoire où c'est stocké : cd /home/pi/mon_site_de_malade
  2. Le générer : sudo bundle exec jekyll build -d /var/www/html
  3. Le déployer : sudo bundle exec jekyll serve --host [IP locale du Raspberry Pi : 192.168.X.XXX] --port:443
Tout ça est bien décrit dans la doc.

Mettre en ligne son blog

Choix d'un nom de domaine

Comme ça me faisait kiffer d'avoir une vraie adresse en .com, je suis allé acheter le nom de domaine chez OVH, pour 13€/an, pas de quoi se ruiner. Sinon vous pouvez prendre un hébergement gratuit de type DNS dynamique (avec No-IP par exemple), c'est juste que ça vous rajoute une extension dans l'adresse genre [nomdedomaine].dyndns.net
Si vous partez sur un nom de domaine à vous chez OVH, leur guide pour éditer sa zone DNS est bien fait.
Ce que ça donne chez moi :

Interface d'OVH pour configurer sa zone DNS

Grosse digression sur l'IP V4 partagée ou CGN

Pénurie d'IP V4

Actuellement il existe une pénurie d'adresses IP V4, autrement dit toutes les adresses IP V4 possibles (par exemple 1.1.1.1) sont déjà utilisées et/ou réservées. Et leur remplacement par des adresses IP V6 (avec un autre format : 2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b, et beaucoup plus de possibilités) a énormément tardé et est difficilement possible actuellement.
Par conséquent, si un FAI (fournisseur d'accès à internet), tel que Orange, Free... gagne de nouveaux clients, il ne peut pas leur donner une nouvelle adresse IP V4, et sans ça bah leur box ne peut pas se connecter à internet.

La parade des FAI

Pour éviter cette situation pour le moins facheuse, ils recourrent à un petit stratagème de filou : partager une même adresse IP V4 entre plusieurs clients en utilisant la technique du CGN (Carrier Grade NAT), sans mettre leurs clients au courant la plupart du temps.

Basiquement ce que le CGN fait c'est : 1 IP V4 publique + 1 port (il y en a 65536 max) = 1 IP V4 privée.
L'IP V4 privée c'est votre adresse perso qui permet de vous identifier au sein du réseau du FAI, parmi tous ses clients avec la même IP V4 publique.
L'IP V4 publique c'est l'adresse utilisée par le FAI pour l'ensemble des clients qui sont derrière (soit un maximum théorique de 65536, même si en pratique c'est beaucoup moins), et c'est aussi cette adresse qui identifie cet ensemble de clients sur internet.

Et si jamais votre FAI fait du CGN, à moins de faire un test, vous ne le saurez pas. Et vous aurez l'impression que votre IP c'est l'IP V4 privée (qui n'existe réellement qu'au sein de votre FAI), alors qu'en réalité la vraie IP qui permet de vous identifier sur internet c'est l'IP V4 publique.

Les inconvénients du CGN

Outre les problèmes légaux d'identification de l'utilisateur que ça peut engendrer (genre vous partagez l'IP V4 publique d'un pédophile ou d'un terroriste, vous risquez de recevoir une visite pas très courtoise de la police), un seul client peut utiliser un port de l'IP V4 publique à la fois.

Supposons, au hasard, que vous auto-hébergez un blog sur un Raspberry Pi chez vous.
Vous allez ouvrir les ports 80 (http) et 443 (https) sur internet, via votre box (ce qu'on appelle du port-forwarding), pour que n'importe qui puisse consulter votre blog sur internet.
Supposons encore, au hasard, que d'autres clients de votre FAI, à qui le FAI a donné la même IP V4 publique que vous, veulent faire la même chose.
A votre avis ça donne quoi ?

Bah c'est pas jojo : tout le monde va ouvrir ses ports 80 et 443 sur sa box, et vérifier que ça fonctionne bien en testant sur son adresse IP V4 Privée. Sauf qu'un seul client peut utiliser les ports 80 et 443 de l'adresse IP V4 publique à un instant t.
Et tous les autres vont péter des câbles en se demandant pourquoi leur blog n'est pas accessible alors qu'ils ont bien ouvert les ports sur leur box. Cet exemple s'applique aussi à d'autres usages assez répandus : VPN (port 1194), P2P (ports 6881 à 6889), jeux en ligne...

Free à la rescousse

Afin de permettre au faible nombre de clients ayant réellement besoin d'avoir une IP V4 publique que pour eux, et donc éviter d'être victime du CGN, Free propose d'avoir une adresse IP V4 publique, qu'ils appellent IP V4 Fullstack, en en faisant simplement la demande sur votre espace freebox en ligne : Interface de Free pour demander une IP V4 Full Stack

Ajout dans Apache

Dans l'article dédié à Nextcloud sur PiMyLifeUp, la méthode pour mettre en ligne un site avec Apache et un nom de domaine est super bien détaillée, et va même jusqu'à expliquer comment forcer la redirection de HTTP vers HTTPS, ce qui est toujours un petit plus en matière de sécurité.
Un autre article qui m'a aussi servi : https://marulanda.me/how-to-jekyll/

Pour faire cohabiter Nextcloud et le blog, j'ai fait en sorte que googlesaitouesttamere.com/nextcloud redirige vers le bon répertoire via le virtual host apache. J'ai fait deux fichiers de configuration apache (dans sites-available et sites-enabled) : un pour le blog et un pour nextcloud.

Pour le blog (et pour la page erreur 404) :
ServerName googlesaitouesttamere.com
DocumentRoot "/var/www/html"
ErrorDocument 404 /404.html

Pour nextcloud :
Alias /nextcloud "/var/www/nextcloud/"
<Directory /var/www/nextcloud/>
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
<IfModule mod_dav.c>
Dav off
</IfModule>
</Directory>

Mise en place du SSL

Pour que ce soit sécurisé un minimum, j'ai installé un certificat Let's Encrypt en suivant cet article, rien de compliqué là-dessus.

Mise en ligne sur les intertubes

Maintenant que tout est paramétré, il faut ouvrir l'accès via sa box en redirigeant les ports 80 et 443 vers le Raspberry Pi : Interface de Freebox OS pour rediriger des ports Pour un peu plus d'infos, voir cet article.

Mise à jour du site

Une fois que c'est déployé, si vous rajoutez un nouvel article plus tard, ou n'importe quelle modif, il suffit de refaire un build : sudo bundle exec jekyll build -d /var/www/html (sans avoir besoin de faire de serve).


Trucs et astuces

Ajout de nouvelles polices d'écriture

Pour avoir une police d'écriture qui soit plus personnalisée pour le titre du blog dans la barre de navigation, la façon généralement proposée est de passer par l'api fonts.googleapis. Autant dire que ça ne me plaisait pas du tout.
J'ai donc téléchargé le fichier *.woff de la police qui me plaisait (Bebas Neue), puis placé le fichier dans le répertoire assets et fait un lien dans un fichier scss tel que :
@font-face {
font-family: "Bebas Neue";
src: url(../BebasNeue-Regular.woff);
}

Gestion des catégories sans plugin

Il existe des plugins pour Jekyll qui permettent de gérer des catégories, mais par principe je préfère ne pas dépendre d'éléments externes. J'ai suivi cet article pour implémenter ça.
Point d'attention, dans les fichiers .md de chaque catégorie il est nécessaire que le nom des fichiers soit en minuscule et sans caractères spéciaux.

Fonctionnalité de recherche instantanée

J'avais comme volonté de ne pas inclure de JavaScript sur ce blog, pour rester le plus minimaliste possible (et parce que j'y connais rien). Le seul écart que j'ai fait est pour cette fonction de recherche (accessible via le lien Recherche dans la barre de navigation).
Je me suis aidé de cet article, même si ça n'a pas été super simple non plus.

Astuces :

  1. Ajouter une variable pour l'adresse du site dans le fichier _config.yml, par exemple vraieurl: googlesaitouesttamere.com et l'utiliser à la place de site.baseurl dans le fichier search.json.
  2. Contenu du search.json (un chouïa modifié par rapport à celui de l'article) : Contenu du fichier search.json

Articles mis en avant

Après la lecture de cet article super intéressant où l'auteur se questionne un peu sur le sens des blogs/sites perso, je rejoignais son raisonnement et trouvais dommage de "subir" le fait d'avoir les articles triés par ordre chronologique, alors que je pense que certains méritent d'être mis en avant. Je me suis aidé de cet article pour mettre ça en place.