Title: Bastille: créer des templates pour vos Jails FreeBSD
Category: sysadmin
Tags: FreeBSD, Bastille, jails, pl-fr
Date: 2021-03-30 8:38
Cover: assets/backgrounds/bastille_gravure.jpg

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][l_iocage]. J'ai ensuite décidé de passer mon serveur
à la maison sous FreeBSD et de tester [Bastille][l_bastillebsd] 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][l_gh_bastille].

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][l_doc_bastille] 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][l_gitlab_templates].

Je vais prendre comme exemple l'installation de [Wallabag][l_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 :

```console
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 :

```console
# 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`:

```console
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 :

```console
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`:

```yaml
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 :

```yaml
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és[^n_support_git]

Pour ce template il suffit de faire :

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

[^n_support_git]: mais c'est [en bonne voie](https://github.com/BastilleBSD/bastille/pull/334)

## 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:

```console
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:

```console
bastille config wallabag set sysvshm new && bastille restart wallabag
```

Et enfin appliquer notre template :

```console
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][l_w_bastille] -- Domaine Public

[l_gitlab_templates]:https://gitlab.com/bastillebsd-templates
[l_iocage]:https://iocage.io/
[l_gh_bastille]:https://github.com/BastilleBSD/bastille.git
[l_doc_bastille]:https://bastille.readthedocs.io/en/latest/
[l_bastillebsd]:https://bastillebsd.org/
[l_wallabag]:https://wallabag.org
[l_w_bastille]:https://commons.wikimedia.org/wiki/File:La_Bastille_20060809.jpg
