đŸ’» TP : Faire un dĂ©ploiement multi-conteneurs

Dans un TP prĂ©cĂ©dent, vous avez vu comment rendre un conteneur joignable depuis l’extĂ©rieur de son environnement d’accueil, Ă  l’aide d’un mĂ©canisme appelĂ© la publication de port. Cependant, la publication de port n’est pas adaptĂ©e lorsque des logiciels exĂ©cutĂ©s dans des conteneurs diffĂ©rents ont besoin de communiquer entre eux.

Dans ce TP, vous allez voir comment rendre possible la communication inter-conteneurs Ă  l’aide de rĂ©seaux virtuels.

1. Tutoriel : premiers réseaux virtuels

Jusqu’ici, le dĂ©ploiement de chaque service a nĂ©cessitĂ© la crĂ©ation d’un seul conteneur Ă  la fois, souvent Ă  l’aide d’une publication de port pour rendre ce conteneur accessible depuis un rĂ©seau local. Or, il est courant qu’un mĂȘme service nĂ©cessite le fonctionnement de plusieurs conteneurs reliĂ©s entre eux − typiquement, un logiciel applicatif associĂ© Ă  un systĂšme de gestion de base de donnĂ©es. Voyons comment dĂ©ployer plusieurs conteneurs mis en rĂ©seau.

1.1. Deux conteneurs sur un mĂȘme rĂ©seau virtuel

1.1.1. Mise en place

Pour commencer, créons un réseau virtuel r1 qui permette de relier plusieurs conteneurs entre eux :

[sur l’environnement de dĂ©ploiement distant]
$ podman network create r1

On peut vĂ©rifier que ce rĂ©seau a bien Ă©tĂ© créé avec la commande suivante, qui liste les rĂ©seaux virtuels existants :

[sur l’environnement de dĂ©ploiement distant]
$ podman network ls

Un conteneur peut ĂȘtre reliĂ© Ă  un rĂ©seau virtuel uniquement lors de sa crĂ©ation. Dans un premier terminal, crĂ©ons un premier conteneur interactif Alpine appelĂ© conteneurA reliĂ© Ă  ce rĂ©seau (Ă  l’aide de l’option --network) :

[sur l’environnement de dĂ©ploiement distant]
$ podman container run --name conteneurA \
                       --rm -ti \
                       --network r1 \
                       docker.io/alpine:3.22

Gardez au chaud ce premier terminal dans lequel s’exĂ©cute conteneurA, et ouvrez un second terminal dans lequel nous allons crĂ©er un second conteneur interactif conteneurB Ă©galement connectĂ© au rĂ©seau appelĂ© r1 :

[sur l’environnement de dĂ©ploiement distant]
$ podman container run --name conteneurB \
                       --rm -ti \
                       --network r1 \
                       docker.io/alpine:3.22

Ensuite, pour tester leur mise en rĂ©seau, nous allons installer dans les deux conteneurs l’utilitaire netcat, qui a l’avantage de permettre de facilement crĂ©er un petit processus serveur et un petit processus client.

Au sein d’un conteneur Alpine, netcat est disponible via le paquet netcat-openbsd installable Ă  l’aide du gestionnaire de paquets apk. On commence donc par installer netcat dans chacun des deux conteneurs :

[dans conteneurA]
# apk update && apk add netcat-openbsd
[dans conteneurB]
# apk update && apk add netcat-openbsd
Utiliser netcat pour du test réseau simple

Une fois netcat installĂ© dans un environnement Linux donnĂ©, il peut ĂȘtre utilisĂ© Ă  l’aide de la commande nc. On peut distinguer deux usages simples de la commande netcat nc :

  • on peut demander Ă  nc de se comporter comme un processus serveur qui Ă©coute sur un port rĂ©seau, de maniĂšre Ă  pouvoir recevoir une connexion requise par un processus client, Ă  l’aide de la commande suivante :

    nc -l <port d'écoute>
    L’option -l signifie listen, ce qui se traduit en "Ă©couter".
  • on peut demander Ă  nc de se comporter comme un processus client qui se connecte Ă  un port rĂ©seau d’un environnement donnĂ© (dĂ©signĂ© par son nom d’hĂŽte), de maniĂšre pouvoir se connecter Ă  un processus serveur exĂ©cutĂ© dans cet autre environnement, Ă  l’aide de la commande suivante :

    nc <nom d'hĂŽte> <port auquel se connecter>
    Un processus serveur nc ne peut pas recevoir plus d’une seule connexion Ă  la fois, ainsi un seul processus client peut se connecter Ă  un processus serveur. Cela n’est pas reprĂ©sentatif du cas gĂ©nĂ©ral dans le monde du logiciel : il est habituel qu’un processus serveur puisse recevoir plusieurs connexions en parallĂšle (par exemple un serveur web peut recevoir des connexions de plusieurs navigateurs web).

Si une de ces commandes se termine instantanĂ©ment, et vous rend la main, c’est que la connexion a Ă©chouĂ© − cela peut arriver si le nom d’hĂŽte et/ou le port renseignĂ© est incorrect ou incohĂ©rent.

Mais Ă  l’inverse, si les deux commandes ne se terminent pas et ne vous rendent pas la main, c’est gĂ©nĂ©ralement qu'une connexion a Ă©tĂ© Ă©tablie entre processus serveur et processus client.

Il est alors possible d’effectuer une saisie au clavier, puis d’appuyer sur EntrĂ©e, pour envoyer un texte au processus serveur, qui l’affiche dĂšs rĂ©ception. À l’inverse, si on Ă©crit un texte cĂŽtĂ© serveur et qu’on appuie sur entrĂ©e, le message s’affiche cĂŽtĂ© client.

Pour arrĂȘter une commande nc en cours d’exĂ©cution, on peut faire la combinaison de touches Ctrl+C dans le terminal concernĂ©.

Faisons l’inventaire de ce que nous avons en place :

  • Un rĂ©seau virtuel appelĂ© r1,

  • Un conteneur appelĂ© conteneurA, reliĂ© Ă  ce rĂ©seau virtuel. Au sein de ce rĂ©seau virtuel, conteneurA est joignable au travers du nom d’hĂŽte conteneurA (identique Ă  son nom de conteneur).

  • Un conteneur appelĂ© conteneurB, reliĂ© au mĂȘme rĂ©seau virtuel. LĂ  aussi, au sein de ce rĂ©seau virtuel, conteneurB est joignable au travers du nom d’hĂŽte conteneurB (identique Ă  son nom de conteneur).

Maintenant, utilisons netcat pour tester cette mise en réseau !

1.1.2. Test 1 : serveur dans conteneurA, client dans conteneurB

Utilisons netcat pour démarrer un processus serveur qui écoute sur le port 5000 du conteneurA :

[dans conteneurA]
# nc -l 5000

Une fois cette cette commande exĂ©cutĂ©e, il semble ne rien se passer. C’est normal : netcat a dĂ©marrĂ© son processus serveur et est en attente d’une connexion, donc il reste (trĂšs) silencieux pour le moment.

Puis utilisons netcat pour démarrer un processus client qui se connecte sur le port 5000 de conteneurA :

[dans conteneurB]
# nc conteneurA 5000

Si la connexion est bien Ă©tablie (lire l’encart sur netcat plus haut), vous pouvez alors :

  • envoyer "bonjour depuis conteneurB !" depuis le processus client exĂ©cutĂ© sur le conteneurB, et vĂ©rifier que le message s’affiche dans le terminal avec le conteneurA,

  • envoyer "bonjour depuis conteneurA !" depuis le processus serveur exĂ©cutĂ© sur le conteneurA, et vĂ©rifier que le message s’affiche dans le terminal avec le conteneurB.

podman network nc
Figure 1. Échange de messages entre les deux conteneurs Alpines

Si tout fonctionne, vous avez fait votre premiÚre mise en réseau de plusieurs conteneurs !

1.1.3. Test 2 : client dans conteneurB, client dans conteneurA

Juste pour dĂ©montrer que la connexion entre les deux conteneurs est bien symĂ©trique, reproduisez le mĂȘme test mais en inversant les deux rĂŽles :

  • dĂ©marrez un processus nc serveur depuis conteneurB, sur un port d’Ă©coute diffĂ©rent de 5000,

  • dĂ©marrer un processus nc client depuis conteneurA pour se connecteur au conteneurB sur le port choisi Ă  l’Ă©tape prĂ©cĂ©dente,

  • Ă©changez des messages dans les deux sens pour vĂ©rifier que tout fonctionne.

1.2. Trois conteneurs sur deux réseaux virtuels

1.2.1. Mise en place

Dans la derniÚre partie de ce tutoriel, voyons comment deux réseaux virtuels peuvent coexister.

Notre objectif va ĂȘtre de garder le premier rĂ©seau, puis de crĂ©er un second rĂ©seau r2, et d’y connecter une partie de nos conteneurs. Nous souhaitons faire en sorte d’avoir :

  • un conteneur conteneurA connectĂ© au rĂ©seau r1,

  • un conteneur conteneurB connectĂ© aux rĂ©seaux r1 et r2,

  • un conteneur conteneurC connectĂ© au rĂ©seau r2.

Commençons par créer le nouveau réseau :

[sur l’environnement de dĂ©ploiement distant]
$ podman network create r2

Vérifions que les deux réseaux co-existent bien :

[sur l’environnement de dĂ©ploiement distant]
$ podman network ls

On peut garder le conteneurA Ă  l’identique, car est dĂ©jĂ  reliĂ© au rĂ©seau r1 comme souhaitĂ©.

Nous devons par contre recrĂ©er le conteneurB car nous souhaitons qu’il soit reliĂ© aux deux rĂ©seaux virtuels. On peut faire les commandes suivantes dans le terminal dĂ©diĂ© au conteneurB :

[sur l’environnement de dĂ©ploiement distant]
$ podman container rm --force conteneurB
$ podman container run --name conteneurB \
                       --rm -ti \
                       --network r1 \
                       --network r2 \
                       docker.io/alpine:3.22

Enfin, dans un troisiÚme terminal, on crée le conteneurC de la sorte :

[sur l’environnement de dĂ©ploiement distant]
$ podman container run --name conteneurC \
                       --rm -ti \
                       --network r2 \
                       docker.io/alpine:3.22

Sur les deux conteneurs Alpine ainsi (re)créés, installez la commande nc comme fait précédemment.

Voyons maintenant ce que ce déploiement jouet permet de faire.

1.2.2. Test 1 : communications depuis le conteneurB

  • Sur le conteneurA, dĂ©marrez un processus serveur nc qui Ă©coute sur le port 8888.

  • Sur le conteneurC, dĂ©marrez un processus serveur nc qui Ă©coute Ă©galement sur le port 8888.

    On peut sans problĂšme ici utiliser le mĂȘme numĂ©ro de port, car chacun de ces ports est ouvert dans un environnement diffĂ©rent (et donc sur une interface rĂ©seau diffĂ©rente).
  • Sur le conteneurB, dĂ©marrez un processus client nc qui se connecte au port 8888 du conteneurA, puis Ă©changez des messages dans les deux sens pour vĂ©rifier que tout fonctionne.

  • Sur le conteneurB, dĂ©marrez un processus client nc qui se connecte au port 8888 du conteneurC, puis Ă©changez des messages dans les deux sens pour vĂ©rifier que tout fonctionne.

Si tout se passe bien, vous pouvez constater que les messages arrivent Ă  s’Ă©changer dans les deux cas :

  • Dans le premier cas, les messages entre conteneurB et conteneurA transitent via le rĂ©seau virtuel r1.

  • Dans le second cas, les messages entre conteneurB et conteneurC transitent via le rĂ©seau virtuel r2.

1.2.3. Test 2 : communication entre conteneurA et conteneurC ?

  • Sur le conteneurA, dĂ©marrez un processus serveur nc qui Ă©coute sur le port 9999.

  • Sur le conteneurC, dĂ©marrez un processus client nc qui tente de se connecter au port 9999 du conteneurA, puis tentez d’Ă©changer des messages entre les deux processus.

Si votre mise en place est correcte, les échanges de messages ne devraient ici
 pas fonctionner !

En effet, mĂȘme s’il existe un rĂ©seau r1 entre conteneurA et conteneurB, et un rĂ©seau r2 entre conteneurB et conteneurC, il n’existe aucun rĂ©seau entre conteneurA et conteneurC. Ainsi il est impossible de crĂ©er une commumnication directe entre les deux.

À retenir

En rĂ©flĂ©chissant bien Ă  quelles connexions sont nĂ©cessaires entre nos conteneurs, on peut s’assurer avec nos rĂ©seaux virtuels quelles communications inter-conteneurs sont possible/autorisĂ©es, et lesquelles ne sont impossibles/interdites.

Ce dernier cas est utile pour Ă©viter que deux processus communiquent entre eux "par erreur" (ou par malice) alors qu’ils ne devraient pas.

2. Tutoriel : dĂ©ployer un service Mealie Ă  l’aide d’un rĂ©seau virtuel

On se propose de déployer un service Mealie, un logiciel libre permettant de stocker et partager des recettes de cuisine. Mealie est capable de fonctionner avec un systÚme de gestion de base de données de type PostgreSQL, on souhaite donc déployer Mealie avec sa propre base de données PostgreSQL.

Avant tout, commencez par crĂ©er sur l’environnement d’accueil un rĂ©pertoire mealie_deployment qu’on utilisera pour nos prochains montages de rĂ©pertoire.

2.1. Réseau virtuel

Commençons par préparer un réseau virtuel qui permettra à nos deux futurs conteneurs de communiquer entre eux.

ExĂ©cutez la commande suivante pour crĂ©er un rĂ©seau virtuel appelĂ© mealie_network :

[sur l’environnement de dĂ©ploiement distant]
$ podman network create mealie_network

On peut vĂ©rifier que ce rĂ©seau a bien Ă©tĂ© créé avec la commande :

[sur l’environnement de dĂ©ploiement distant]
$ podman network ls

Le réseau virtuel devrait apparaßtre dans la liste, avec son propre identifiant unique et le driver bridge.

Nous n’utiliserons pas d’autres drivers rĂ©seau que bridge.

2.2. Conteneur PostgreSQL

On peut maintenant préparer le systÚme de gestion de base de données PostgreSQL.

On choisit d’utiliser l’image de conteneur officielle PostgreSQL situĂ©e sur le Docker Hub. En lisant la documentation de l’image, on observe que :

  • Le point d’entrĂ©e de l’image est l’exĂ©cution du logiciel PostgreSQL,

  • Les donnĂ©es de la base de donnĂ©es sont stockĂ©es dans le rĂ©pertoire /var/lib/postgresql/data du conteneur,

  • Par dĂ©faut, le logiciel PostgreSQL Ă©coute sur le port 5432 du conteneur,

  • Par dĂ©faut, lors du premier lancement d’un conteneur, un compte PostgreSQL est créé, ainsi qu’une base de donnĂ©es vide Ă  laquelle ce compte peut accĂ©der. Des variables d’environnement sont disponibles pour configurer cela :

    • POSTGRES_USER permet de spĂ©cifier le nom du compte PostgreSQL,

    • POSTGRES_PASSWORD, permet de spĂ©cifier le mot de passe du compte POSTGRES_USER,

    • POSTGRES_DB permet de spĂ©cifier le nom de la base de donnĂ©es créée pour le compte POSTGRES_USER.

Dans le répertoire mealie_deployment que vous avez préparé, créez un sous-répertoire appelé db-data dans lequel nous stockerons les données de la base de données. Utilisez la commande pwd pour obtenir le chemin absolu du répertoire db-data, et notez ce chemin absolu quelque part.

ExĂ©cutez ensuite la commande suivante pour crĂ©er votre conteneur PostgreSQL, en version 16, avec pour nom mealie_db, en l’ajoutant sur le rĂ©seau mealie_network, et en prĂ©parant un compte PostgreSQL appelĂ© mealie avec pour mot de passe mealie_password et pour base de donnĂ©es mealie_db.

[sur l’environnement de dĂ©ploiement distant]
$ podman container run --rm \
                       --detach \
                       --name mealie_db \
                       --network mealie_network \
                       --mount type=bind,source="<chemin absolu db-data>",target="/var/lib/postgresql/data" \
                       --env POSTGRES_USER=mealie \
                       --env POSTGRES_PASSWORD=mealie_password \
                       --env POSTGRES_DB=mealie_data \
                       docker.io/postgres:16
Mais puisque PostgreSQL Ă©coute sur le port 5432, pourquoi n’avons-nous pas effectuĂ© une publication de ce port ? La raison est la suivante : nous ne souhaitons pas que ce conteneur PostgreSQL soit accessible par n’importe quel logiciel sur le rĂ©seau du serveur de dĂ©ploiement. À la place, nous souhaitons qu’il soit uniquement accessible par notre application, Ă  savoir Mealie, au travers du rĂ©seau virtuel mealie_network que nous avons prĂ©parĂ©.

VĂ©rifiez que le conteneur est bien en exĂ©cution avec :

[sur l’environnement de dĂ©ploiement distant]
$ podman container ps

Puis vĂ©rifiez les logs du conteneur pour s’assurer que tout va bien :

[sur l’environnement de dĂ©ploiement distant]
$ podman container logs mealie_db

Vers la fin, vous devriez notamment voir la ligne :

PostgreSQL init process complete; ready for start up.

Et quelques lignes plus loin :

database system is ready to accept connections

VĂ©rifiez enfin que le conteneur est bien sur le rĂ©seau mealie_network Ă  l’aide de la commande :

[sur l’environnement de dĂ©ploiement distant]
$ podman container ps --filter network=mealie_network

Si le conteneur est bien dans la liste, c’est que tout est OK !

2.3. Conteneur Mealie

Il ne nous reste plus qu’Ă  lancer un conteneur Mealie, et de lui permettre d’utiliser notre base de donnĂ©es PostgreSQL situĂ©e dans le premier conteneur.

Mealie est dĂ©veloppĂ© Ă  l’aide d’un projet sur la forge logicielle Github, et utilise le registre de conteneurs Github pour stocker les images de conteneur de l’application. Les images seront donc accessibles Ă  l’aide du registre ghcr.io, sous le nom mealie-recipes/mealie.

En lisant la documentation de Mealie, on trouve les informations utiles suivantes :

  • Le point d’entrĂ©e de l’image est l’exĂ©cution du logiciel Mealie,

  • Le logiciel Ă©coute par dĂ©faut sur le port 9000 du conteneur,

  • Le logiciel a besoin de stocker des fichiers (notamment des photos tĂ©lĂ©versĂ©es pour illustrer les recettes de cuisine) dans le rĂ©pertoire /app/data/ du conteneur,

  • On peut configurer l’accĂšs Ă  la base de donnĂ©es Ă  l’aide des variables d’environnement suivantes :

    • DB_ENGINE permet d’indiquer le type de la base de donnĂ©es, avec soit la valeur sqlite, soit la valeur postgres,

    • POSTGRES_SERVER permet d’indiquer le nom d’hĂŽte rĂ©seau du serveur PostgreSQL Ă  utiliser pour stocker les donnĂ©es,

    • POSTGRES_DB permet d’indiquer le nom de la base de donnĂ©es Ă  utiliser au sein du serveur PostgreSQL,

    • POSTGRES_USER permet d’indiquer le compte Ă  utiliser pour se connecter au serveur PostgreSQL,

    • POSTGRES_PASSWORD permet d’indiquer le mot de passe Ă  utiliser pour se connecter au serveur PostgreSQL,

    • POSTGRES_PORT permet d’indiquer le port Ă  utiliser pour se connecter au serveur PostgreSQL.

Avec tout cela en tĂȘte, prĂ©parez et exĂ©cutez la commande suivante, afin de crĂ©er un conteneur Mealie, en version v1.0.0-RC1.1, appelĂ© mealie, sur le rĂ©seau virtuel mealie_network, avec une publication de port et avec la bonne configuration pour se connecter Ă  la base de donnĂ©es PostgreSQL prĂ©parĂ©e Ă  l’Ă©tape prĂ©cĂ©dente :

[sur l’environnement de dĂ©ploiement distant]
$ podman container run --rm \
                       --detach \
                       --name mealie \
                       --network mealie_network \
                       --publish <mon port réseau>:9000 \
                       --env DB_ENGINE=postgres \
                       --env POSTGRES_SERVER=mealie_db \
                       --env POSTGRES_DB=mealie_data \
                       --env POSTGRES_USER=mealie \
                       --env POSTGRES_PASSWORD=mealie_password \
                       --env POSTGRES_PORT=5432 \
                       ghcr.io/mealie-recipes/mealie:v1.0.0-RC1.1

en remplaçant <mon port réseau> par un port réseau de votre choix de votre plage de port attribuée.

Toutes les informations Ă©crites dans les variables POSTGRES_ du conteneur Mealie doivent absolument correspondre exactement Ă  la configuration effectuĂ©e du conteneur PostgreSQL au prĂ©alable. On notera par exemple que POSTGRES_SERVER correspond au nom donnĂ© au conteneur PostgreSQL, car ce nom est Ă©galement un nom d’hĂŽte rĂ©seau au sein d’un rĂ©seau virtuel mealie_network.

VĂ©rifiez que le conteneur est bien en exĂ©cution avec :

[sur l’environnement de dĂ©ploiement distant]
$ podman container ps

Puis vĂ©rifiez les logs du conteneur pour s’assurer que tout va bien :

[sur l’environnement de dĂ©ploiement distant]
$ podman container logs mealie

Vers la fin, vous devriez notamment voir la ligne :

Uvicorn running on http://0.0.0.0:9000
Cette ligne indique que Mealie Ă©coute sur le port 9000, mais n’oubliez pas que nous avons publiĂ© ce port sur un port diffĂ©rent de l’environnement d’accueil !

VĂ©rifiez enfin que le conteneur est bien sur le rĂ©seau mealie_network Ă  l’aide de la commande :

[sur l’environnement de dĂ©ploiement distant]
$ podman container ps --filter network=mealie_network

Si les deux conteneurs sont bien dans cette liste, c’est que tout est OK !

2.4. Tests puis nettoyage

On peut dĂ©sormais tester notre logiciel dĂ©ployĂ©. Sur votre poste Linux, ouvrez Firefox, et accĂ©dez Ă  l’adresse http://podman:<mon port rĂ©seau>.

Pour rappel, ici <mon port rĂ©seau> correspond au port de publication choisi pour le conteneur Mealie dans l’Ă©tape prĂ©cĂ©dente.

Vous devriez faire face à un écran de connexion du logiciel Mealie. Vous pouvez vous connecter avec le compte créé par défaut qui a pour utilisateur changeme@example.com et pour mot de passe MyPassword.

Ensuite, vous pouvez utiliser le bouton CrĂ©er puis Importer une recette par son URL afin d’importer une recette de cuisine Ă  partir d’une page web. Saisissez par exemple cette URL https://deliacious.com/2020/03/babka-cannelle-vegan.html puis validez. L’import devrait fonctionner, et si vous accĂ©dez au menu Rechercher Ă  fauche, votre recette devrait ĂȘtre listĂ©e.

Félicitations, vous avez effectué votre premier déploiement multi-conteneurs !

On peut maintenant faire un peu de nettoyage avant de passer Ă  la suite :

[sur l’environnement de dĂ©ploiement distant]
$ podman container rm -f mealie
$ podman container rm -f mealie_db
$ podman network rm mealie_network

3. Exercice : dĂ©ployer un service Kanboard+MariaDB avec un rĂ©seau virtuel

3.1. ÉnoncĂ©

On souhaite Ă  nouveau dĂ©ployer un service Kanboard, tout comme dans le TP prĂ©cĂ©dent. Cette fois-ci, on souhaite utiliser le fait que Kanboard est capable de stocker des donnĂ©es dans un systĂšme de gestion de base de donnĂ©es compatible MySQL. On souhaite donc que notre nouveau dĂ©ploiement soit composĂ© d’un conteneur Kanboard d’une part, et d’un conteneur compatible MySQL d’autre part.

Concernant la base de donnĂ©es, on choisit d’utiliser l’image de conteneur officielle pour le logiciel MariaDB, un systĂšme de gestion de base de donnĂ©es compatible MySQL. En lisant la documentation de l’image, on trouve les informations utiles suivantes :

  • Le point d’entrĂ©e de l’image est l’exĂ©cution du logiciel MariaDB,

  • Le logiciel Ă©coute par dĂ©faut sur le port 3306 du conteneur,

  • Le logiciel stocke ses donnĂ©es dans le rĂ©pertoire /var/lib/mysql du conteneur,

  • Par dĂ©faut, lors du premier lancement d’un conteneur, un compte MariaDB est créé, ainsi qu’une base de donnĂ©es vide Ă  laquelle ce compte peut accĂ©der. Des variables d’environnement sont disponibles pour configurer cela (de maniĂšre assez similaire Ă  l’image de conteneur PostgreSQL vue prĂ©cĂ©demment) :

    • MARIADB_USER permet de spĂ©cifier le nom du compte MariaDB,

    • MARIADB_PASSWORD permet de spĂ©cifier le mot de passe du compte MARIADB_USER,

    • MARIADB_DATABASE permet de spĂ©cifier le nom de la base de donnĂ©es créée pour le compte MARIADB_USER,

    • MARIADB_ROOT_PASSWORD est une variable obligatoire qui permet de spĂ©cifier un mot de passe administrateur pour tout le logiciel MariaDB.

Concernant le logiciel Kanboard, mĂȘme si le contexte est le mĂȘme que dans le TP prĂ©cĂ©dent, il nous faut Ă©galement savoir comment configurer un conteneur pour qu’une base de donnĂ©es externe soit utilisĂ©e. En parcourant la documentation, on peut lire qu’il est possible de configurer un conteneur Kanboard Ă  l’aide d’une unique variable d’environnement :

  • DATABASE_URL permet de spĂ©cifier une URL de base de donnĂ©es qui prend la forme suivante :

    mysql://<nom utilisateur>:<mot de passe>@<nom d'hÎte>:<port>/<nom base de données>

    avec :

    • <nom utilisateur> le nom d’utilisateur MariaDB Ă  utiliser,

    • <mot de passe> le mot de passe pour l’utilisateur MariaDB

    • <nom d’hĂŽte> le nom d’hĂŽte Ă  utiliser pour se connecter au serveur MariaDB,

    • <port’hĂŽte> le port rĂ©seau Ă  utiliser pour se connecter au serveur MariaDB,

    • <nom base de donnĂ©es> le nom de la base de donnĂ©es Ă  utiliser.

3.2. Questions

  1. PrĂ©parez et exĂ©cutez une commande pour dĂ©ployer un service Kanboard, sous la forme d’un conteneur Kanboard reliĂ© Ă  un conteneur MariaDB en suivant avec les contraintes suivantes:

    • Le nom du conteneur Kanboard doit ĂȘtre kanboard_instance.

    • Le nom du conteneur MariaDB doit ĂȘtre kanboard_db.

    • L’image de conteneur Kanboard utilisĂ©e doit ĂȘtre celle correspondant Ă  l’Ă©tiquette v1.2.32.

    • L’image de conteneur MariaDB utilisĂ©e doit ĂȘtre celle correspondant Ă  l’Ă©tiquette 11.1.

    • L’application Kanboard doit ĂȘtre accessible par une publication de port,

    • Les donnĂ©es du conteneur Kanboard doivent ĂȘtre stockĂ©es dans l’environnement d’accueil.

    • Les donnĂ©es du conteneur MariaDB doivent ĂȘtre stockĂ©es dans l’environnement d’accueil.

  2. Une fois les conteneurs en exĂ©cution, utilisez Firefox depuis votre poste de travail Linux pour accĂ©der Ă  la page d’accueil de Kanboard, en utilisant la publication de port que vous avez rĂ©alisĂ©e.

  3. Testez l’application de maniĂšre similaire Ă  ce qui Ă©tait demandĂ© dans le TP prĂ©cĂ©dent.

  4. Une fois authentifiĂ© dans l’application avec le compte par dĂ©faut, cliquez tout en haut Ă  droite sur l’icone utilisateur, puis accĂ©dez aux PrĂ©fĂ©rences. Dans les informations affichĂ©es, vĂ©rifiez que le type de base de donnĂ©es est bien mysql.

Vous allez constater que les donnĂ©es créées par le conteneur MariaDB ne peuvent pas directement ĂȘtre supprimĂ©es de l’environnement d’accueil, car votre compte utilisateur ne possĂšde pas les permissions suffisantes. Rendez-vous vers la fin du sujet de TP pour plus d’informations Ă  ce sujet.

4. Exercice : dĂ©ployer lldap, Kanboard et Mealie Ă  l’aide de rĂ©seaux virtuels

Cet exercice a Ă©tĂ© terminĂ© tardivement et ajoutĂ© aprĂšs le dĂ©but des premiĂšres sĂ©ances pour ce sujet de TP. À ce titre il n’est donc pas obligatoire, mais il reste trĂšs intĂ©ressant Ă  faire pour approfondir les notions de ce chapitre.

Pour finir ce TP, on souhaite effectuer un déploiement un peu plus complexe qui fait principalement collaborer trois logiciels différents :

  • Une instance du logiciel Kanboard (adossĂ© Ă  une instance MariaDB comme base de donnĂ©es)

  • Une instance du logiciel Mealie (adossĂ© Ă  une instance PostgreSQL comme base de donnĂ©es)

  • Et enfin une instance du logiciel _lldap, un logiciel qui fournit un service d’authentification de type LDAP.

Dans cet exercice, l’idĂ©e est de configurer Kanboard et de configurer Mealie de maniĂšre Ă  ce que chacun des deux logiciels dĂ©lĂšgue sur l’instance lldap pour l’authentification d’un utilisateur. Ainsi, un compte utilisateur créé au sein de l’instance lldap pourra Ă  la fois ĂȘtre utilisĂ© pour se connecter Ă  Mealie, et pour se connecter Ă  Kanboard.

On souhaite dĂ©ployer chaque logiciel sous la forme d’un conteneur, soit un total de 5 conteneurs Ă  dĂ©ployer !

4.1. Présentation de LDAP et lldap

Lightweight Directory Access Protocol (LDAP) est une norme qui permet Ă  un logiciel serveur d’agir comme un annuaire d’utilisateurs (le serveur LDAP), et qui permet Ă  d’autres logiciels (les clients LDAP) de dĂ©lĂ©guer la gestion et l’authentification de leurs utilisateurs Ă  un serveur LDAP existant. C’est une maniĂšre rĂ©pandue de centraliser un ensemble unique de comptes utilisateurs, qui permettront de se connecter de maniĂšre unifier Ă  tout un ensemble de services informatiques.

lldap (qui signifie Light LDAP implementation for authentication) est un logiciel libre qui permet de dĂ©ployer un serveur LDAP simplifiĂ© et suffisant pour gĂ©rer un annuaire lĂ©ger d’utilisateurs, et pour gĂ©rer l’authentification d’utilisateurs sur diffĂ©rents services.

En lisant la documentation lldap, on découvre les informations utiles suivantes :

  • une image de conteneur lldap est disponible sur le registre de conteneur Docker Hub (donc docker.io) sous le nom lldap/lldap.

  • Une Ă©tiquette valide pour cette image est 2025-10-14

  • Le point d’entrĂ©e de cette image est le dĂ©marrage d’un processus lldap

  • Au sein du conteneur, le processus lldap stocke ses donnĂ©es au sein du rĂ©pertoire /data.

  • Par dĂ©faut, un processus lldap Ă©coute simultanĂ©ment sur deux ports rĂ©seaux :

    • le port 17170, via lequel on peut se connecter Ă  lldap Ă  l’aide d’un navigateur web, pour pouvoir utiliser l’interface d’administration de lldap ; cette interface permet de crĂ©er un compte, lister les comptes disponibles, etc.

    • le port 3890, via lequel un autre logiciel peut se connecter Ă  lldap Ă  l’aide du protocole LDAP, et qui permet Ă  cet autre logiciel de dĂ©lĂ©guer Ă  lldap l’authentification utilisateur.

  • lldap doit ĂȘtre configurĂ© Ă  l’aide des variables d’environnement suivantes :

    • LLDAP_JWT_SECRET : doit contenir une chaĂźne de caractĂšres gĂ©nĂ©rĂ©e alĂ©atoirement, utilisĂ©e Ă  des fins cryptographiques par lldap

    • LLDAP_KEY_SEED : tout comme LLDAP_JWT_SECRET, doit contenir une chaĂźne de caractĂšres gĂ©nĂ©rĂ©e alĂ©atoirement, utilisĂ©e Ă  des fins cryptographiques par lldap

    • LLDAP_LDAP_USER_PASS : mot de passe du compte administrateur (dont l’identifiant est admin)

    • LLDAP_LDAP_BASE_DN : dĂ©finit le distinguished name de base de l’annuiaire LDAP, et s’Ă©crit sous la forme dc=example,dc=com ou bien juste dc=example

4.2. Étape 1 : prĂ©parer le plan de dĂ©ploiement

Avant de vous lancer, répondez soigneusement aux questions suivantes :

  • Quels sont les conteneurs qu’il va falloir crĂ©er ?

  • Quels sont les rĂ©seaux virtuels qu’il va falloir crĂ©er ?

    Pour simplifier lĂ©gĂšrement, on peut considĂ©rer que tous conteneurs ayant besoin de contacter lldap peuvent ĂȘtre mis sur un mĂȘme rĂ©seau virtuel.
  • Quels sont les publications de port qui vont ĂȘtre nĂ©cessaires ?

    Il ne faut pas exposer tous les ports rĂ©seau sur le rĂ©seau local ! RĂ©flĂ©chissez bien Ă  ceux qu’il est nĂ©cessaire de publier, et si vous avez un doute lĂ  dessus, demandez Ă  votre intervenant de TP.
  • Quels sont les montages de fichiers/rĂ©pertoires qui vont ĂȘtre nĂ©cessaires ?

4.3. Étape 2 : crĂ©er tous les rĂ©seaux virtuels nĂ©cessaires

Pour chaque rĂ©seau virtuel anticipĂ© Ă  l’Ă©tape prĂ©cĂ©dente, le crĂ©er avec podman.

4.4. Étape 3 : dĂ©ployer lldap

Déployez une instance lldap qui suit votre plan de déploiement, et avec également les contraintes suivantes :

  • le conteneur doit s’appeler lldap_instance

  • les donnĂ©es de lldap doivent ĂȘtre persistĂ©es dans l’environnement de dĂ©ploiement

  • vous utiliserez les valeurs suivantes pour les diffĂ©rentes variables d’environnement :

    • LLDAP_JWT_SECRET : la valeur de votre choix,

    • LLDAP_KEY_SEED : la valeur de votre choix,

    • LLDAP_LDAP_BASE_DN : la valeur 'dc=monannuaire'

    • LLDAP_LDAP_USER_PASS : la valeur motdepasse

Connectez vous ensuite Ă  l’interface web d’administration de lldap, connectez vous avec le compte admin, puis utilisez le bouton Create a user pour crĂ©er un compte utilisateur de votre choix

Ne perdez pas le mot de passe que vous aurez choisi, il sera nécessaire aux étapes suivantes !

4.5. Partie 4 : déployer Kanboard

En suivant votre plan de dĂ©ploiement, dĂ©ployez une base de donnĂ©es PostgresQL, ainsi qu’une instance Kanboard.

Pour le dĂ©ploiement de Kanboard, ajoutez les variables d’environnement suivantes pour configurer l’authentification au travers du serveur lldap :

  • LDAP_AUTH : mettre la valeur true

  • LDAP_BIND_TYPE : mettre la valeur user

  • LDAP_SERVER : mettre une valeur de la forme ldap://<nom d’hĂŽte>:<numĂ©ro port>, oĂč <nom d’hĂŽte> est le nom d’hĂŽte permettant d’atteindre le serveur LDAP, et <numero port> le numĂ©ro de port auquel se connecter sur ce serveur pour contacter le serveur LDAP

  • LDAP_USERNAME : mettre la valeur uid=%s,ou=people,dc=monannuaire

  • LDAP_USER_BASE_DN : mettre la valeur ou=people,dc=monannuaire

  • LDAP_USER_FILTER : mettre la valeur uid=%s

Ici nous vous fournissons la solution pour la plupart des valeurs, car configurer une connexion LDAP est une entreprise assez tortueuse.

Une fois votre instance Kanboard dĂ©marrĂ©e, testez de vous connecter Ă  l’aide du compte utilisateur que vous avez créé dans la partie 3. Si cela fonctionne, c’est bon !

4.6. Partie 5 : déployer Mealie

En suivant votre plan de dĂ©ploiement, dĂ©ployez une base de donnĂ©es MariaDB, ainsi qu’une instance Mealie.

Pour le dĂ©ploiement de Mealie, ajoutez les variables d’environnement suivantes pour configurer l’authentification au travers du serveur lldap :

  • LDAP_AUTH_ENABLED : mettre la valeur true

  • LDAP_SERVER_URL : mettre une valeur de la forme ldap://<nom d’hĂŽte>:<numĂ©ro port>, oĂč <nom d’hĂŽte> est le nom d’hĂŽte permettant d’atteindre le serveur LDAP, et <numero port> le numĂ©ro de port auquel se connecter sur ce serveur pour contacter le serveur LDAP

  • LDAP_BASE_DN : mettre la valeur ou=people,dc=monannuaire

  • LDAP_QUERY_BIND : mettre la valeur cn=admin,ou=people,dc=monannuaire

  • LDAP_QUERY_PASSWORD : mettre la valeur motdepasse (Ă  savoir le mot de passe du compte admin créé au lancement de lldap)

  • LDAP_ID_ATTRIBUTE : mettre la valeur uid

  • LDAP_NAME_ATTRIBUTE : mettre la valeur uid

  • LDAP_MAIL_ATTRIBUTE : mettre la valeur mail

À nouveau ici nous vous fournissons la solution pour la plupart des valeurs, car configurer une connexion LDAP est une entreprise assez pĂ©nible.

Une fois votre conteneur dĂ©marrĂ©, accĂ©dez Ă  Mealie Ă  l’aide d’un navigateur, et tentez de vous connecter Ă  l’aide du compte utilisateur prĂ©parĂ© en partie 3. Si vous arrivez Ă  vous connecter, c’est tout bon !

5. Prise de recul sur le travail rĂ©alisĂ© dans les sĂ©ances de TP jusqu’ici

Prenons un peu de recul.

La premiĂšre chose Ă  remarquer est que, malgrĂ© les dĂ©boires que vous avez pu rencontrer, les diffĂ©rents dĂ©ploiements que vous avez rĂ©alisĂ© en TP n’ont normalement pas reprĂ©sentĂ© une quantitĂ© de travail trĂšs importante. Certes il peut ĂȘtre laborieux de prĂ©parer les bonnes commandes et de crĂ©er les bons conteneurs dans le bon ordre avec les bonnes configurations − et c’est pour cela que nous avons tout un cours ! − mais le nombre d’actions Ă  effectuer pour faire le dĂ©ploiement Ă  proprement parler est gĂ©nĂ©ralement trĂšs bas (seulement quelques commandes par situation).

En outre, vous avez pu dĂ©ployer ces logiciels sans avoir la moindre connaissance technique de leur fonctionnement interne, ou des technologies qu’ils utilisent, ou des dĂ©pendances qu’ils nĂ©cessitent. Sans le savoir, vous avez dĂ©ployĂ© un logiciel dĂ©veloppĂ© en C (nginx), un autre dĂ©veloppĂ© en Python + JavaScript (mealie), et un autre dĂ©veloppĂ© en PHP (Kanboard), le tout alors que chacune de ces technologies gĂšre totalement diffĂ©remment ses dĂ©pendances logicielles. Vous n’avez jamais eu besoin d’installer un moteur d’exĂ©cution PHP, ou un interprĂ©teur Python, ou des bibliothĂšques natives pour C. SacrĂ©e prouesse !

Tout cela illustre la grande efficacitĂ© de la conteneurisation pour le dĂ©ploiement des logiciels. C’est simple : faire tous ces dĂ©ploiements n’aurait simplement pas Ă©tĂ© possible dans un TP de M1 Informatique sans utiliser cette mĂ©thode, car cela aurait nĂ©cessitĂ© de votre part une bien plus grande maĂźtrise du travail d’administrateur⋅ice systĂšme.

Bien entendu, ce qui a mis ces déploiements à votre portée est le travail important réalisé en amont pour préparer toutes les images de conteneurs que vous avez utilisées. La suite des travaux pratique consistera donc à découvrir comment préparer de telles images pour les logiciels que vous souhaitez déployer.

6. Exercices additionnels

Pour ceux qui auraient terminé ce TP avant le temps alloué en séance, voici quelques exercices supplémentaires moins guidés et plus "libres" que ceux demandés précédemment.

6.1. DĂ©ploiement d’un serveur ForgeJo

ForgeJo est une forge logicielle permettant de gĂ©rer des dĂ©veloppements logiciels. On peut y crĂ©er des projets avec rĂ©fĂ©rentiel Git et avec des outils d’organisation classiques (tickets, navigation dans le code, revues de code, etc.). C’est donc une alternative au logiciel Gitlab, plus lĂ©gĂšre mais avec Ă©galement moins de fonctionnalitĂ©s.

On notera que ForgeJo a besoin d’Ă©couter sur deux ports rĂ©seau diffĂ©rents :

  • le port 3000, qui permet de se connecter Ă  ForgeJo Ă  l’aide d’un navigateur web

  • le port 22, qui permet de se connecter Ă  ForgeJo Ă  l’aide d’une connexion SSH, afin de pouvoir utiliser Git Ă  l’aide du protocole SSH

Pour ce dernier exercice, vous effectuerez un dĂ©ploiement d’une instance ForgeJo, avec les contraintes suivantes :

  • on utilisera une base de donnĂ©es MariaDB (compatible MySQL)

  • on configurera ForgeJo pour qu’il utilise correctement le port de publication SSH que vous aurez choisi, Ă  l’aide de l’option SSH_PORT

  • on utilisera une image avec une Ă©tiquette possĂ©dant le suffixe -rootless, pour s’assurer d’avoir une image compatible Podman

  • plutĂŽt que de configurer le logiciel Ă  l’aide de variables d’environnement, on utilisera un fichier de configuration app.ini, en se basant sur ce fichier exemple fourni par les dĂ©veloppeurs de ForgeJo.

Cette page de la documentation vous explique comment ForgeJo peut ĂȘtre configurĂ©, et rĂ©sume toutes les options permettant de configurer le logiciel.

Cette autre page de la documentation vous donne des informations sur les images de conteneur ForgeJo disponibles, en particulier un exemple de rĂ©fĂ©rence d’image. Elle comporte Ă©galement des exemples de fichiers Ă©crits avec le langage Compose, non Ă©tudiĂ© dans ce cours pour le moment.

Pour valider votre dĂ©ploiement, vous pouvez :

  • crĂ©er un compte sur votre instance ForgeJo,

  • ajouter votre clĂ© publique SSH Ă  votre compte,

  • crĂ©er un projet Ă  l’aide de ce compte,

  • effectuer un clone Git par SSH de ce nouveau projet,

  • ajoutez un fichier, puis effectuez une validation (commit) et envoi (push)

6.2. Déploiement de Simplestblog

Faites un dĂ©ploiement par vous mĂȘme d’une instance de Simplestblog

Vous pouvez bien entendu vous baser sur les commandes déjà vues pendant le cours.

Sur la page du projet, vous pouvez accĂ©der Ă  l’ensemble des images de conteneurs disponibles en vous rendant dans DĂ©ploiement → Registre de conteneur.