📘 Créer et manipuler des conteneurs

Dans ce chapitre nous allons découvrir comment créer des conteneurs à partir d’images de conteneur déjà existantes. Nous verrons comment accomplir cela à l’aide d’outils appelés des moteurs de conteneurisation. Plus précisément nous allons découvrir le moteur de conteneurisation qui sera utilisé tout au long du cours, à savoir Podman.

Ce chapitre présente les premiers éléments nécessaires pour déployer des logiciels partir d’images de conteneur existantes. Cependant, ce chapitre n’explique pas comment déployer un logiciel pour lequel aucune image de conteneur n’a été préparée pour son déploiement − cela sera vu dans le chapitre sur la création d’images.

1. Moteurs de conteneurisation

Un moteur de conteneurisation est le principal logiciel qu’on utilise pour la conteneurisation. C’est un logiciel notamment capable de :

  • Créer et exécuter un conteneur à partir d’une image de conteneur,

  • Gérer le cycle de vie d’un conteneur (stopper, relancer, inspecter, supprimer, etc.)

  • Stocker un ensemble d’images de conteneurs au sein d’un stockage local,

  • Récupérer des image de conteneurs depuis un registre de conteneurs distant.

La plupart des moteurs sont également capable de construire de nouvelles images de conteneurs (sera vu dans le chapitre sur la création d’images).

Passons en revue les principaux moteurs de conteneurisation existants:

  • LXC, logiciel libre apparu en 2008 et développé au départ par l’entreprise américaine IBM, est un des premiers moteurs de conteneurisation. Entièrement dédié aux environnements d’accueil de type Linux, l’objectif pour LXC était au départ avant tout de fournir une alternative aux technologues de virtualisation, avec l’idée qu’un conteneur contienne un environnement très complet pour exécuter un ou plusieurs logiciels. C’est une solution aujourd’hui en perte de vitesse.

  • Docker, logiciel libre apparu en 2013 et développé par l’entreprise américaine Docker, Inc., est le moteur de conteneurisation qui a révolutionné la conteneurisation. C’est avec Docker que s’est démocratisé l’idée de créer autant de conteneurs que de logiciels à exécuter, ainsi que l’idée de permettre la diffusion et la réplication facile d’un logiciel à l’aide d’images de conteneurs. Le registre de conteneurs Docker Hub, accessible publiquement et gratuitement et offrant une immense libraire d’images de conteneurs, a beaucoup contribué à ce succès. C’est encore aujourd’hui très largement le moteur de conteneurisation le plus utilisé.

  • Kubernetes, logiciel libre apparu en 2014, au départ développé par Google puis aujourd’hui par la Cloud Native Computing Foundation, est une solution logicielle complète pour orchestrer et déployer des conteneurs sur une infrastructure. Kubernetes peut utiliser des moteurs de conteneurisation existants, comme Docker ou Podman, et inclut également son propre moteur de conteneurisation. L’idée de Kubernetes est définir des nœuds, chaque nœud étant un environnement d’accueil qui exécute un processus Kubernetes. On peut ensuite déclarer quels conteneurs on souhaite exécuter, en combien d’exemplaires, et sur quels nœuds, et Kubernetes se charge de faire tout le déploiement nécessaire. Kubernetes est une solution complexe, riche et très utilisée dans l’industrie, notamment pour faire fonctionner des logiciels nécessitant un passage à l’échelle (scaling) dynamique important.

  • Podman, logiciel libre apparu en 2017 et développé par l’entreprise américaine Red Hat, est l’un des principaux "concurrents" à Docker. C’est un moteur de conteneurisation avec trois caractéristiques importantes :

    • Podman est le seul moteur de conteneurisation qui ne nécessite pas de faire exécuter un démon en processus d’arrière plan de l’environnement d’accueil. Sans rentrer dans les détails, l’interface en ligne de commande podman est capable de créer et gérer des conteneurs en allant directement interagir avec le système d’exploitation, ce qui évite un processus supplémentaire comme nécessite par exemple Docker.

    • Podman a été le premier moteur de conteneurisation à permettre une exécution rootless de conteneurs, autrement dit sans avoir besoin de posséder des droits d’administrateur root au sein de l’environnement d’accueil. C’est un changement très important car il permet de limiter les droits d’accès de l’utilisateur système qui exécuter le moteur de conteneurisation, et donc les droits du moteur de conteneurisation lui-même, ce qui est très souhaitable en terme de sécurité informatique. Aujourd’hui, même si les alternatives permettent également un mode d’exécution rootless, comme Docker, Podman est la seule solution à le proposer par défaut.

    • Podman a choisi de fournir une expérience utilisateur aussi proche de celle de Docker que possible, en allant jusqu’à copier la syntaxe et la sémantique de la quasi totalité des commandes Docker. La force de ce choix est de permettre de très facilement remplacer un usage de Docker par un usage de Podman, en remplaçant juste la commande docker par la commande podman.

Pourquoi Podman dans ce cours ?

Dans ce cours, nous allons nous concentrer sur Podman pour trois raisons :

  • Tout ce que vous apprendrez avec Podman pourra directement s’appliquer à Docker (qui reste la solution la plus utilisée aujourd’hui).

  • Au niveau infrastructure informatique de l’Université, Podman est plus facile à mettre en œuvre auprès des étudiants car il peut facilement fonctionner sans droits administrateurs.

  • Cela vous permet de prendre conscience que la conteneurisation ne se limite pas à Docker !

podman white

2. Créer et manipuler un conteneur

2.1. Cycle de vie d’un conteneur

Pour créer et démarrer un conteneur avec Podman, on utilise la commande suivante :

$ podman container run --name <nom du conteneur> \
                              <autres options> \
                              <référence d'image>
                              <point d'entrée explicite>

où :

  • <nom du conteneur> est le nom donné au conteneur. Si aucun nom n’est donné, un nom aléatoire est automatiquement généré par le moteur.

  • <référence d’image> est une référence d’image valide.

  • <autres options> est une liste d’options supplémentaires et optionnels.

  • <point d’entrée explicite> est une valeur optionnelle qui permet de démarrer le conteneur avec un autre processus que le point d’entrée configuré dans l’image (par exemple pour forcer le conteneur à démarrer avec un interpréteur de commandes comme bash).

Concernant les <autres options>, un très grand nombre de possibilités existent et peuvent être combinées. Voyons déjà quelques options de base :

  • --rm : définit que le conteneur sera automatiquement détruit lors de la fin de son exécution. Cela affecte son cycle de vie, comme expliqué peu après.

  • --detach (version courte : -d ) : démarre le conteneur en arrière-plan et sans l’attacher à l’interpréteur de commande utilisé. C’est une option couramment utilisée lors d’un déploiement, de manière à garder la main sur l’interpréteur de commande.

Deux autres options sont également importantes lorsqu’on souhaite pouvoir interagir au clavier avec un conteneur :

  • --tty (version courte : -t) : permet au conteneur de posséder son propre terminal virtuel, nécessaire pour pouvoir ouvrir un interpréteur de commandes dans le conteneur.

  • --interactive (version courte : -i) : si le conteneur n’est pas lancé avec --detach, permet au conteneur de recevoir des commandes clavier.

En pratique, on utilise toujours --tty et --interactive ensemble (souvent en version courte combinée : -ti), car on souhaite généralement pouvoir à la fois interagir au clavier avec le conteneur, et permettre à ce dernier de nous écrire ses résultats dans un terminal.

Il est également possible de créer un conteneur sans l’exécuter tout de suite avec la commande suivante, qui possède la même syntaxe que la commande podman container run, et avec les mêmes options disponibles :

$ podman container create --name <nom du conteneur>
                                 <autres options>
                                 <référence d'image>
En pratique on utilise principalement podman container run directement.

Pour stopper un conteneur en exécution :

$ podman container stop <nom du conteneur>

Pour démarrer un conteneur :

$ podman container start <nom du conteneur>

Si le conteneur que l’on redémarre était initialement un conteneur interactif (créé avec --tty --interactive) on peut également utiliser conjointement les options --attach --interactive (version courte : -ai) pour reprendre en mode interactif l’exécution du conteneur arrêté :

$ podman container start --attach --interactive <nom du conteneur>

Pour redémarrer un conteneur (équivaut à stop puis start) :

$ podman container restart <nom du conteneur>

Pour supprimer un conteneur arrêté :

$ podman container rm <nom du conteneur>

On peut également utiliser l’option --force (version courte : -f) pour supprimer un conteneur encore en exécution :

$ podman container rm --force <nom du conteneur>

Si on résume tout le cycle de vie d’un conteneur tel que ces commandes le permettent, on obtient la machine à états suivante :

cycle vie conteneur.drawio
Figure 1. Cycle de vie d’un conteneur avec les commandes Podman (si conteneur créé sans --rm)

Attention, dans le cas où le conteneur est créé avec l’option --rm, on obtient une machine à états légèrement différente, car il sera alors impossible de retrouver l’état Stoppé une fois le conteneur en exécution :

cycle vie conteneur rm.drawio
Figure 2. Cycle de vie d’un conteneur avec les commandes Podman (si conteneur créé avec --rm)
Exemple 1. Cycle de vie d’un conteneur nginx

On souhaite créer un conteneur à l’aide de l’image du serveur web nginx disponible sur le Docker Hub à l’emplacement docker.io/nginx :

  • en nommant le conteneur mon_serveur_web,

  • en utilisant la dernière version de l’image, donc l’étiquette latest,

  • en mode détaché, c’est à dire avec exécution en arrière plan.

On exécute donc :

$ podman container run --name mon_serveur_web \
                       --detach \
                       docker.io/nginx:latest

Plus tard, on souhaite supprimer le conteneur. Pour cela, on commence par l’arrêter :

$ podman container stop mon_serveur_web

On peut ensuite le supprimer :

$ podman container rm mon_serveur_web
Exemple 2. Exécution d’un conteneur Alpine en mode interactif

On souhaite créer un conteneur à l’aide de l’image Alpine Linux disponible sur le Docker Hub à l’emplacement docker.io/alpine :

  • en nommant le conteneur alpine_test,

  • en utilisant la version de l’image 3.18,

  • en mode interactif, donc non détaché et avec les options permettant d’ouvrir un terminal,

  • avec suppression automatique du conteneur lors de la fin de son exécution,

On exécute donc :

$ podman container run --name alpine_test \
                       --tty \
                       --interactive \
                       --rm \
                       docker.io/alpine:3.18

Suite à cela, comme le point d’entrée de l’image Alpine est l’interpréteur de commandes sh, et comme nous avons bien spécifié --tty on se voit présenter un interpréteur de commandes dans un terminal virtuel :

/ #

Et comme nous avons spécifié --interactive, nous pouvons saisir des commandes. Par exemple on peut afficher les répertoires disponibles avec ls :

/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var

Ou encore se promener dans les répertoires avec cd et créer un fichier vide avec touch, et lister ce fichier à nouveau avec ls :

/ # cd /root
~ # touch "mon_fichier"
~ # ls
mon_fichier

Enfin, on envoie la commande exit ce qui termine l’exécution de l’interpréteur de commandes, et donc du conteneur :

~ # exit

On reprend alors la main, et le conteneur a été automatiquement supprimé puisque nous avions utilisé l’option --rm.

Notons pour cette section une dernière commande pour supprimer tous les conteneurs arrêtés (très pratique pour faire le ménage) :

$ podman container prune
Pour rappel, si un conteneur a bien été conçu pour être éphémère, alors cette commande ne devrait jamais créer de problèmes !

2.2. Inspecter et observer des conteneurs

Une fois des conteneurs créés et/ou en exécution, des commandes sont disponibles pour observer les conteneurs créés

Pour lister les conteneurs en exécution :

$ podman container list

La liste de conteneurs affichée sera structurée avec les colonnes suivantes :

  • CONTAINER ID : Identifiant unique du conteneur.

  • IMAGE : Chemin de l’image utilisée pour créer le conteneur.

  • COMMAND : Point d’entrée exécuté au sein du conteneur.

  • CREATED : Date de création du conteneur.

  • STATUS : État du conteneur, avec trois états possibles :

    • Created signifie que le conteneur a été créé, mais n’a jamais été exécuté.

    • Up signifie que le conteneur est en exécution.

    • Exited signifie que le conteneur est stoppé.

  • PORTS : La liste de toutes les publications de ports en cours.

  • NAMES : Les noms du conteneur (souvent il n’y en a qu’un seul).

On peut également utiliser l’option --all (version courte : -a) pour afficher tous les conteneurs créés, y compris ceux qui sont stoppés.

$ podman container list --all

Pour afficher les derniers logs d’un conteneur donné :

$ podman container logs <nom du conteneur>

On peut également utiliser l’option --follow (version courte : -f) pour espionner les logs au fur et à mesure qu’ils apparaissent :

$ podman container logs --follow <nom du conteneur>

Pour afficher toutes les méta-données associées à un conteneur donné :

$ podman container inspect <nom du conteneur>
Le texte produit par cette dernière commande est intéressant, mais très long ! En outre il est affiché en JSON et est donc peu lisible à l’œil nu. On y trouve tous les montages, toute la configuration réseau, toutes les publications de ports, des informations détaillées sur l’état actuel du conteneur, etc.
Exemple 3. Inspection et observation d’un conteneur nginx

On exécute à nouveau un conteneur nginx comme en Exemple 1 :

$ podman container run --name mon_serveur_web \
                       --detach \
                       docker.io/nginx:latest

Puis on liste les conteneurs en exécution :

$ podman container list

CONTAINER ID  IMAGE                           COMMAND               CREATED             STATUS             PORTS       NAMES
bac5cc3f5685  docker.io/library/nginx:latest  nginx -g daemon o...  About a minute ago  Up About a minute              mon_serveur_web

On trouve bien notre conteneur et toutes les informations associées.

On souhaite ensuite afficher les derniers logs :

$ podman container logs mon_serveur_web

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/09/09 09:55:48 [notice] 1#1: using the "epoll" event method
2023/09/09 09:55:48 [notice] 1#1: nginx/1.25.2
2023/09/09 09:55:48 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2023/09/09 09:55:48 [notice] 1#1: OS: Linux 6.4.14-200.fc38.x86_64
2023/09/09 09:55:48 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 524288:524288
2023/09/09 09:55:48 [notice] 1#1: start worker processes
2023/09/09 09:55:48 [notice] 1#1: start worker process 24
2023/09/09 09:55:48 [notice] 1#1: start worker process 25
2023/09/09 09:55:48 [notice] 1#1: start worker process 26
2023/09/09 09:55:48 [notice] 1#1: start worker process 27
2023/09/09 09:55:48 [notice] 1#1: start worker process 28
2023/09/09 09:55:48 [notice] 1#1: start worker process 29
2023/09/09 09:55:48 [notice] 1#1: start worker process 30
2023/09/09 09:55:48 [notice] 1#1: start worker process 31

On trouve bien les derniers messages affichés par nginx, qui a été exécuté en point d’entrée.

Enfin, on tente d’inspecter le conteneur :

$ podman container inspect mon_serveur_web

[
     {
          "Id": "bac5cc3f5685d8af38549ea8f7ccdabd39fea2bcb174c5c030b237f9d38254e3",
          "Created": "2023-09-09T11:55:48.275344022+02:00",
          "Path": "/docker-entrypoint.sh",
          "Args": [
               "nginx",
               "-g",
               "daemon off;"
          ],
          "State": {
               "OciVersion": "1.1.0-rc.3",
               "Status": "running",
               "Running": true,
               "Paused": false,
               "Restarting": false,
               "OOMKilled": false,
               "Dead": false,
               "Pid": 137333,
        …
        …
        …

Le résultat est un très très long texte en format JSON avec des informations détaillées sur le conteneur.

3. Agir sur un conteneur déjà créé

3.1. Exécuter une commande dans un conteneur en exécution

Un conteneur en exécution est toujours en train d’exécuter la commande spécifiée dans l’image comme point d’entrée du conteneur. Cependant, il peut être très utile, par exemple pour des tâches de maintenance ou de débogage, d’exécuter une commande arbitraire au sein du conteneur alors que ce dernier est toujours en exécution. Cette commande arbitraire s’exécutera donc en parallèle de la commande du point d’entrée en cours d’exécution

On procède ainsi :

$ podman container exec <nom du conteneur> <options> <commande>

Parmi les nombreuses <options> possibles, les seules importantes à noter sont --tty et --interactive qui permettent (tout comme pour podman container run) de rendre possible les interactions au clavier avec la commande lancée.

Exemple 4. Initialisation de la base de données de Simplestblog

Supposons que nous ayons réussi à déployer Simplestblog sous la forme d’un conteneur nommé simplestblog_app.

Il se trouve que Simplestblog n’est pas utilisable immédiatement car le logiciel a besoin, lors de sa première exécution, d’effectuer une initialisation de la base de données qui lui a été confiée. Cette initialisation doit être déclenchée à l’aide d’une commande indiquée dans la documentation technique de Simplestblog, et s’écrit flask --app simplestblog init-db.

Pour exécuter cette commande dans le conteneur Simplestblog, on exécute donc la commande suivante :

$ podman container exec simplestblog_app flask --app simplestblog init-db
Exemple 5. Ouverture d’une session sh dans Automatic-Image-Converter

Supposons avoir réussi déployer Automatic-Image-Converter sous la forme d’un conteneur.

On souhaite ouvrir une session interactive au sein du conteneur afin d’aller voir comment les choses se déroulent. On sait que dans le conteneur est disponible l’interpréteur de commandes sh.

On exécute donc la commande suivante, en oubliant pas --tty et --interactive de manière à obtenir un retour console et une saisie clavier possible :

$ podman container exec --tty --interactive aic sh

En retour cela nous affiche une session interactive sh ouverte :

/ #

On peut alors, par exemple, vérifier que l’exécutable de notre image est bien présent à la racine du système de fichiers virtuel (c’est à dire /) :

/ # ls
__cacert_entrypoint.sh  dev                     inputs                  mnt                     proc                    sbin                    tmp
app.jar                 etc                     lib                     opt                     root                    srv                     usr
bin                     home                    media                   outputs                 run                     sys                     var

On constate que app.jar est bien présent comme attendu.

On souhaite également vérifier que la commande d’exécution de notre logiciel est la bonne, à l’aide de la commande ps :

/ # ps
PID   USER     TIME  COMMAND
    1 root      0:00 java -jar /app.jar /inputs /outputs png 5000
   20 root      0:00 sh
   29 root      0:00 ps

On peut voir, avec la première ligne, qu’on exécute bien Automatic-Image-Converter comme souhaité.

Pas de fenêtre graphique depuis un conteneur

Les méthodes présentées ci-après sont parfaitement adaptées pour interagir avec un logiciel exécuté dans un conteneur lorsque ce logiciel possède une interface textuelle (en "ligne de commande") ou bien qui se rend accessible via un accès réseau (par exemple Simplestblog), ou encore pour d’autres logiciels qui s’exécutent en tâche de fond sans avoir besoin d’interaction directe (par exemple Automatic-Image-Converter).

En revanche, il n’est généralement pas directement possible d’exécuter dans un conteneur un logiciel qui nécessite une fenêtre graphique. Par exemple on ne peut pas lancer un éditeur de texte graphique ou un navigateur web depuis un conteneur : le système d’exploitation restreint refusera toute demande d’affichage graphique émise de la part du logiciel.

Quelques astuces permettent tout de même au conteneur de créer une fenêtre graphique, que ce soit en partageant un accès à un serveur d’affichage graphique de l’environnement d’accueil (typiquement un serveur X linux), ou bien en exécutant un serveur de partage d’écran dans le conteneur (typiquement un serveur VNC). Mais ces astuces ne font pas partie de l’usage prévu de Docker, et sont loin d’être des pratiques courantes. Pour aller plus loin, on peut tout de même s’intéresser au logiciel x11docker, l’un des plus avancés sur la question.

Si on souhaite un environnement isolé pour des applications graphiques, plutôt que d’utiliser la conteneurisation, on privilégiera d’autres techniques cousines comme l’empaquetage portable (par exemple AppImage) ou bien l’empaquetage bac-à-sable (par exemple Flatpak ou Snap).

3.2. Échanger des fichiers avec un conteneur

Jusqu’à présent, nous avons vu qu’on conteneur était par construction isolé de l’environnement d’accueil dans lequel il s’exécute. Bien que cette caractéristique soit souhaitable, cela limite énormément les usages d’un logiciel conteneurisé, puisqu’il ne peut pas interagir avec le "monde extérieur" pour échanger des messages ou des fichiers.

Nous verrons dans ce cours différentes manières d’ouvrir volontairement des interstices cette isolation, et dans cette section nous allons voir la manière la plus plus simple : la copie de fichiers.

D’abord, podman nous permet de copier un fichier (ou répertoire) depuis l’environnement d’accueil vers un conteneur, à l’aide de la commande suivante :

$ podman container cp <fichier ou répertoire> <nom conteneur>:<emplacement conteneur>

avec :

  • <fichier ou répertoire> : le fichier ou répertoire à copier,

  • <nom conteneur> : le nom du conteneur dans lequel copier le fichier,

  • <emplacement conteneur> : l’emplacement au sein du conteneur dans lequel copier le fichier.

On peut également inverser les arguments positionnels pour copier un fichier (ou répertoire) depuis le conteneur vers l’environnement d’accueil :

$ podman container cp <nom conteneur>:<fichier ou répertoire conteneur> <emplacement>

avec :

  • <nom conteneur> : le nom du conteneur depuis lequel copier le fichier,

  • <fichier ou répertoire conteneur> : le fichier ou répertoire au sein du conteneur qu’on souhaite copier,

  • <emplacement> : l’emplacement dans l’environnement d’accueil où copier le fichier.

Exemple 6. Copie d’une photo dans un conteneur Automatic-Image-Converter

Supposons à nouveau avoir réussi déployer Automatic-Image-Converter sous la forme d’un conteneur, avec pour nom de conteneur aic_instance. Au sein du conteneur, le logiciel Automatic-Image-Converter a été configuré de manière à lire les fichiers présents dans l’emplacement /inputs du conteneur, afin de générer des fichiers JPG dans l’emplacement /outputs du conteneur.

On souhaite convertir deux fichiers, on décide donc de les copier au bon emplacement dans le conteneur :

$ podman container cp ./ma_photo1.png aic_instance:/inputs
$ podman container cp ./ma_photo2.png aic_instance:/inputs

On attend un peu, puis on exécute la commande ls dans le conteneur pour vérifier que la conversion a bien produit un fichier :

$ podman container exec aic_instance ls /outputs
ma_photo1.png.jpg
ma_photo2.png.jpg

Enfin, on récupère tout le répertoire contenant les fichiers convertis à l’aide d’une copie dans le sens inverse (vers notre machine de travail) :

$ podman container cp aic_instance:/outputs .

4. Configurer un logiciel conteneurisé

Nous avons vu qu’un déploiement de logiciel nécessite de configurer le logiciel concerné pour le contexte considéré. Mais comment configurer un logiciel conteneurisé, sachant que nous ne pouvons pas directement manipuler le logiciel depuis l’environnement d’accueil ?

On distingue généralement deux stratégies : l’utilisation de variables d’environnement, et l’utilisation de fichiers de configuration.

4.1. Passer des variables d’environnement à un conteneur

Il est facilement possible de définir des variables d’environnement au sein d’un conteneur à l’aide de l’option suivante pour la commande podman container run :

  • --env (version courte : -e) : définit une variable d’environnement dans le conteneur, avec la syntaxe <nom de la variable>=<chaîne de caractères>.

Une variable d’environnement ainsi définie peut être soit directement utilisée par le logiciel exécuté, soit peut servir à paramétrer le point d’entrée du logiciel (sera présenté dans le chapitre sur la création d’images).

Exemple 7. Passage d’une variable d’environnement à un conteneur Alpine

On crée un conteneur de manière analogue à Exemple 2, mais on souhaute cette fois-ci définir une variable d’environnement appelée HELLO contenant la chaîne de caractères "WORLD".

On exécute donc :

$ podman container run --name alpine_test \
                       --tty \
                       --interactive \
                       --rm \
                       --env HELLO="WORLD" \
                       docker.io/alpine:3.18

Une fois dans le conteneur, si on affiche le contenu de la variable d’environnement HELLO, on peut voir qu’elle contient bien la valeur que nous avions confiée :

~ # echo $HELLO
WORLD
D’autres exemples seront présentés dans de futurs chapitres, notamment comment utiliser concrètement des variables d’environnement pour configurer des conteneurs Simplestblog et Automatic-Image-Converter.

4.2. Passer un fichier de configuration à un conteneur

Une autre manière courante de configurer un conteneur est l’utilisation d’un fichier de configuration transmis au logiciel exécuté dans le conteneur.

Cela peut être accompli de deux manières :

  • Soit en copiant le fichier de configuration au sein du conteneur (voir section dédiée plus haut),

  • Soit en réalisant un montage de répertoire, ce qui permet de garder le fichier de configuration dans l’environnement d’accueil. Nous verrons ce principe dans le chapitre suivant !