Les conteneurs (ou containers en anglais), c’est vraiment très pratique. Virtualiser un package applicatif de façon à ce qu’il tourne de manière autonome mais avec des interfaces basiques (fichiers et réseaux) permet de se passer de VM complètes avec ce qu’elles supposent d’installation d’OS gourmands et potentiellement onéreux en termes de licences.
J’ai récemment pu déployer trois solutions open source sur mon Syno via conteneurs. Pour conserver les données générées par ces conteneurs, le principe est toujours le même : un volume (autrement dit un dossier partagé entre Docker et ses conteneurs) : ce n’est pas obligatoire, mais extrêmement conseillé, notamment pour ne pas tout perdre au moment de mettre à jour les conteneurs.
En revanche, pour ce qui est de l’interfaçage réseau croissant en termes de complexité : Bitwarden, Nextcloud et Pi-hole.
Level 1 : Bitwarden
Bitwarden est un gestionnaire de mots de passe simple et efficace dont la version gratuite fait déjà une large partie de ce qu’on peut en attendre, mais s’il y a une chose à héberger chez soi si on le peut, c’est bien ses identifiants web et autre numéros de carte bancaire.
Bitwarden n’a fondamentalement que deux besoins : un port d’accès en entrée pour l’interface web et un accès internet en sortie pour la synchronisation.
Pour couvrir ce besoin, le mode default bridge de Docker est suffisant : la sortie sur internet est directement active, et le bridge agit comme une sorte de NAT permettant d’attribuer un port de l’hôte (à définir soi-même) avec le port 80 de l’interface de Bitwarden. Seule difficulté rencontrée : le serveur DNS utilisé par l’application est le même que celui fourni par le DHCP du réseau, et ceci ne permet pas d’adresser l’IP de l’hôte lui-même.
Level 2 : Nextcloud
Nextcloud est une solution complète de stockage de données de type cloud. Il dispose de nombreux modules d’extensions et connecteurs divers permettant d’en faire une véritable suite collaborative professionnelle. Personnellement, mon cahier des charges était simple : synchronisation de fichiers, de contacts et d’agendas.
Par défaut, Nextcloud fonctionne avec une base de données SQLite intégrée au package, mais les développeurs recommandent fortement d’en limiter l’usage à des tests préliminaires et de passer à une base plus « pro » (MySQL/MariaDB ou PostGreSQL) avant toute mise en production. Et c’est là que ça se complique : dès que l’on choisit de suivre cette recommandation, cela signifie qu’il faut créer une interface réseau avec une DB, qui peut être la machine hôte (ici le Syno) ou bien un autre conteneur.
C’est cette seconde possibilité que j’ai choisie, car je préfère que la base de données intégrée du Syno soit réservé aux applicatifs du DSM. J’ai donc installé en parallèle un conteneur MariaDB. En théorie, l’interfaçage entre les deux packages peut se faire en mode default bridge, mais je suis tombé sur un piège : ce mode ne permet pas de forcer une IP fixe aux conteneurs, ni de leur affecter de hostname. Et comme Docker (en tout cas dans sa version DSM) semble aimer à faire changer les IP attribuées aux conteneurs, ce lien peut sauter à tout moment, rendant Nextcloud inopérant.
La solution que j’ai identifiée est d’utiliser un user-defined bridge, le default bridge étant naturellement trop limité – et avec le recul, je pense que c’est voulu, afin de pousser les admins à utiliser d’autres modes plus sécurisés. Globalement, un user-defined bridge fonctionne de la même façon que le default bridge, mais on lui associe un réseau de son choix : j’ai opté pour 10.10.10.0/24, avec une passerelle en 10.10.10.1.
Au moment de (re)déployer un conteneur, on peut alors choisir de le connecter à ce bridge et ainsi de lui affecter une IP fixe et même un hostname qui sera reconnu via requête DNS.
Attention : afin que le reverse-proxy du Syno soit bien supporté, il est nécessaire d’ajouter une instruction au fichier config.php :
docker exec -it -u www-data NextCloud bash -c './occ config:system:set overwriteprotocol --value="https"'
Level 3 : Pi-hole
Pi-hole est un astucieux bloqueur de publicités et de traqueurs utilisant le principe du « DNS menteur », c’est à dire qu’il se place en intermédiaire au serveur DNS pour filtrer les requêtes correspondant à des serveurs connus pour distribuer ce type de contenus. Au passage, c’est ce même système qu’utilise la fonction « bloquer les publicités » des Freebox.
Pi-hole existe en version conteneur, mais l’interfaçage réseau est plus complexe, et ce pour la raison suivante : une requête DNS utilise toujours un port standard (53 en UDP ou TCP), ce qui implique que ces ports doivent être libres sur l’hôte si l’on souhaite utiliser un mode bridge. Or, dans mon cas, j’utilise le Syno comme résolveur DNS, ce qui impose donc de trouver autre chose.
Docker intègre un autre mode d’interconnexion réseau, un driver appelé macvlan : en pratique, il s’agit plus ou moins d’un virtual switch qu’on trouve sur les principales solutions de VM : on crée des réseaux virtuels adossés à une interface physique, et les machines associées disposent alors d’une stack IP complète. Attention, cependant : le nom macvlan semble impliquer qu’on crée un VLAN entier (donc avec subnet et passerelle associées), mais c’est faux. En réalité, il s’agit plus d’un sous-réseau du LAN physique qui vient se greffer à ce dernier. Ici, on crée donc un subnet à host unique 10.1.1.52/32, qui sera également l’adresse IP du conteneur Pi-hole.
La création d’un tel réseau n’est pas chose aisée : après avoir suivi plusieurs tutoriels, j’ai noté 4 étapes principales.
- Créer une configuration du réseau : c’est là qu’on définit à la fois l’adressage du réseau et l’interface parent (ici : « ovs_eth0 ») :

- Créer une instance du réseau : pas de paramètre particulier ici, il suffit de choisir la configuration précédemment créée dans le menu (attention : bien cocher l’option Enable manual container attachment) :

- Associer le nouveau réseau avec l’interface physique et l’activer, grâe aux commandes suivantes (attention : ces commandes sont peut-être inutiles – à vérifier) :
ip link add mac0 link ovs_eth0 type macvlan mode bridgeip addr add 10.9.9.1/24 dev mac0ifconfig mac0 up
- Définir une route statique sur le routeur du LAN désignant l’hôte (i.e. le NAS) comme le next-hop pour le réseau 10.9.9.0/24
Une fois ceci fait, on (re)déploie le conteneur en lui affectant l’adresse IP prévue dans le nouveau subnet, ainsi que la passerelle et les serveurs DNS standards, et il se comporte alors comme une véritable machine dans le LAN. Il ne reste plus qu’à définir cette IP comme résolveur DNS dans le serveur DHCP, et Pi-hole peut alors remplir sa fonction.