Bastille: créer des templates pour vos Jails FreeBSD

Quand on parle de conteneurs, la majorité pense à Docker, mais il n’y a pas que ça dans la vie, il existe aussi les jails BSD (entre autres).

Introduites avec la version 4 de FreeBSD (sortie en mars 2000), le principe des Jails est de partager les ressources d’une machine en plusieurs mini-systèmes autonomes.

C’est un peu le pendant des conteneurs LXC sous GNU/Linux (première version sortie le 6 août 2008).

C’est par FreeNAS que j’ai découvert FreeBSD et les jails; d’abord en utilisant Warden puis iocage. J’ai ensuite décidé de passer mon serveur à la maison sous FreeBSD et de tester Bastille pour la gestion de mes Jails.

Bastille (ou BastilleBSD)

C’est un programme écrit en shell par Christer Edwards. Son but est de faciliter la gestion des Jails tout en adoptant le principe du KISS. Bien entendu c’est Open-Source — licence BSD 3-Clause — et le code source est disponible sur Github.

Il est disponible directement dans les dépôts binaires de FreeBSD ou via les ports. Il est aussi possible de l’installer directement depuis les sources.

L’utilisation de base de Bastille est relativement simple et je ne vais pas détailler ici la mise en place et l’utilisation de base: la documentation est là pour ça et elle est très bien faite.

Créer un Patron

Une des forces de Bastille est la possibilité de créer des “patrons” (ou templates) pour vos conteneurs. Il devient alors simple de déployer des services en deux lignes de commandes.

Un dépôt Gitlab contenant des patrons tout prêts est disponible ici.

Je vais prendre comme exemple l’installation de Wallabag avec PostgreSQL comme système de base de données, Nginx comme serveur web et PHP-fpm.

L’organisation du template

Les templates sont positionnés dans le répertoire /usr/local/bastille/templates sous la forme <dépôt>/<template>. Dans le cas qui nous intéresse ephase/bastille_wallabag.

Le répertoire est organisé comme ceci :

bastille_wallabag
├── Bastillefile
├── etc
│   ├── nginx
│   │   └── nginx.conf
│   └── php-fpm.d
│       └── wallabag.conf
└── www
    └── wallabag
        └── app
            └── config
                └── parameters.yml

Les répertoires www et etc seront copiés dans le répertoire /usr/local/ de notre jail. Ils contiennent respectivement la configuration de Wallabag et les configurations pour PHP-FPM et Nginx.

Le fichier Bastillefile

C’est le point central de la création de notre conteneur, c’est ici que nous allons décrire les actions à effectuer. Dans notre exemple, voici le fichier :

# Declare arguments
ARG WALLABAG_VERSION=2.4.2
ARG DBNAME=wallabag
ARG DBUSER=u_wallabag
ARG DBPASS=mypass
ARG SECRET=mysecret
ARG FQDN=http://${JAIL_IP}
ARG LOCALE=en

# Install packages
PKG php74-session php74-ctype php74-dom php74-simplexml php74-json php74-gd php74-mbstring php74-xml php74-tidy php74-iconv php74-curl php74-gettext php74-tokenizer php74-bcmath php74-intl php74-pdo_pgsql php74-composer php74-sockets php74-xmlreader php74-zlib postgresql12-server nginx git

SYSRC postgresql_enable=YES
SYSRC php_fpm_enable=YES
SYSRC nginx_enable=YES

CP etc /usr/local/

# Service, sysvshm must be new in jail.conf or postgre
SERVICE postgresql initdb
SERVICE postgresql start
SERVICE php-fpm start
SERVICE nginx start

# Create role and database
CMD echo "CREATE ROLE ${DBUSER} WITH LOGIN ENCRYPTED PASSWORD '${DBPASS}'" | su postgres -c psql
CMD echo "CREATE DATABASE ${DBNAME} OWNER ${DBUSER};" | su postgres -c psql
CMD echo "GRANT ALL PRIVILEGES ON DATABASE ${DBNAME} TO ${DBUSER};" | su postgres -c psql

# Download wallabag
CMD mkdir -p /usr/local/www/wallabag
CMD git clone --branch ${WALLABAG_VERSION} --depth 1 https://github.com/wallabag/wallabag.git /usr/local/www/wallabag
CP www /usr/local

# Process config file
RENDER /usr/local/www/wallabag/app/config/parameters.yml

# Launch installation via composer
CMD chown -R www:www /usr/local/www/wallabag
CMD cd /usr/local/www/wallabag && su -m www -c "composer install --no-dev --no-cache -o --no-scripts"
CMD cd /usr/local/www/wallabag && su -m www -c "php bin/console wallabag:install --env=prod -n"

Si vous avez déjà vu ou écrit des Dockerfiles, alors la syntaxe de notre Bastillefile vous paraîtra familière : une commande en majuscule suivie de ses arguments. Nous allons détaller ce fichier d’exemple.

Une commande s’écrit sur une seule ligne. Il n’est pas possible d’utiliser \ pour continuer une ligne. Tout ce qui est précédé du caractère # est considéré comme un commentaire.

Les arguments / variables

Déclaré avec le mot clé ARG suivi de son nom et éventuellement de sa valeur par défaut, ils peuvent être définis lors de l’application du template avec l’option --arg:

bastille template jailname depot/template --args DBNAME=madatabase

Ces arguments sont accessibles ensuite dans notre template, que se soit dans notre Bastillefile et autres fichiers que nous interpréterons avec la commande RENDER (voir plus bas). Nous les utiliserons sous la forme ${<nom_variable>}.

${JAIL_IP} et ${JAIL_NAME} sont des variables accessibles de base contenant respectivement l’adresse IP et le nom de la jail créée.

Les packages

La commande PKG permet d’installer des packages binaires via pkg il suffit de mettre ensuite la liste des paquets nécessaire. Ici tout un tas de truc relatif à PHP, Postgresql et Nginx.

Copie de fichiers

La commande CP permet de copier des fichiers vers la jails. Il est possible de copier des fichiers/répertoires. La syntaxe est la suivante :

CP <source> <destination>

Si la <source> commence par un /, le chemin est absolu, sinon il est relatif au dossier du template.

CP peut être remplacé par COPY

rendre un fichier

La commande RENDER permet de “compiler” un fichier texte en remplaçant les variables par leurs valeurs. Penon un extrait de notre fichier parameter.yml:

parameters:
    database_name: ${DBNAME}
    database_user: ${DBUSER}
    database_password: ${DBPASS}

Après avoir copié le fichier et exécuté la commande RENDER /usr/local/www/wallabag/app/config/parameters.yml nous obtenons :

parameters:
    database_name: wallabag
    database_user: u_wallabag
    database_password: mypass

Sysrc

SYSRC permet d’ajouter des lignes dans le fichier /etc/rc.conf.

exécuter des commandes

Pour exécuter des commandes dans notre jail, il faut utiliser CMD suivie de la commande à exécuter. Il est utilisé de nombreuse fois dans notre Bastillefile et notamment avec les variables définies par ARG:

  • créer la base de données, et les accès
  • installer Wallabag depuis les sources.

Gérer ses templates avec git

Les templates c’est bien, mais les gérer avec git c’est mieux. Il est en effet possible de récupérer ses teplates avec la commande bastille bootstrap. Pour l’instant seuls les dépôts Github et Gitlab sont supportés1

Pour ce template il suffit de faire :

bastille bootstrap https://github.com/ephase/bastille_wallabag

Appliquer notre template

Je vais partir du principe que bastille est déjà configuré et fonctionnel. Au moment de la rédaction de cet article, la dernière version stable de FreeBSD est la 12.2.

Commençons par créer notre jail:

bastille create -V wallabag 12.2-RELEASE 192.168.1.100/24 igb0

Il nous faut installer PosgreSQL, pour que ça fonctionne correctement, il est nécessaire d’activer les segments de mémoire partagés et de redémarrer notre jail:

bastille config wallabag set sysvshm new && bastille restart wallabag

Et enfin appliquer notre template :

bastille template wallabag ephase/bastille-wallabag \
  --arg DBPASS=`openssl rand -base64 16` --arg SECRET=`openssl rand -base64 16`

L’instance Wallabag sera accessible sur le réseau local à l’adresse http://192.168.1.100

En conclusion

Nous avons vu comment utiliser la fonction template de Bastille pour créer facilement une instance Wallabag. Nous n’avons cependant pas abordé les commandes INCLUDE, MOUNT, RDR ou LIMIT, ce qui pourrait donner lieu à un autre article.

J’espère en tout cas vous avoir donné envie d’essayer.

Crédits

  • Image de couverture : La bastille avant 1789 Reproduction d’une gravure du XVIIIe siècle exposée dans le musée de la tour Montparnasse. source — Domaine Public

  1. mais c’est en bonne voie