Améliorez vos compétences avec ce tutoriel Docker Compose

Si vous vous demandez comment créer des conteneurs Docker reproductibles avec Docker Compose, vous êtes au bon endroit. Dans ce tutoriel étape par étape sur Docker Compose, vous allez apprendre à créer des conteneurs simples, à mapper les ports avec Docker Compose jusqu’à des scénarios multi-conteneurs complexes.

Êtes-vous prêt ? Allons-y !

Prérequis

Si vous souhaitez suivre pas à pas ce tutoriel, assurez-vous d’avoir ce qui suit :

  1. A fresh install of Ubuntu Server LTS with SSH Enabled. This guide will use Ubuntu Server LTS 20.04.1 as the Docker host machine.
  2. A computer with VS Code installed (optional). This guide will use Visual Studio Code 1.52.1 to SSH to the Docker host and run commands.
  3. L’extension SSH officielle de VS Code installée et connectée à l’hôte Docker. (facultatif)

Qu’est-ce que Docker Compose ?

Les commandes uniques peuvent être très longues dans Docker. Prenez l’exemple ci-dessous. Cet exemple crée un conteneur pour une application logicielle appelée bookstack.

docker create \
   --name=bookstack \
   -e PUID # UID de l'utilisateur qui prendra possession de l'application/fichiers \
   -e PGID # GID de l'utilisateur qui prendra possession de l'application/fichiers \
   -e DB_USER # L'utilisateur de la base de données \
   -e DB_PASS # Le mot de passe de la base de données \
   -e DB_HOST # L'hôte de la base de données \
   -e DB_DATABASE # La base de données à utiliser \
   -e APP_URL # L'URL à partir de laquelle votre application sera accessible (nécessaire pour le bon fonctionnement du proxy inverse) \
   -v /host/path/to/config:/config # Emplacement des données téléchargées \
   -p 80:80/tcp # Port de l'interface utilisateur Web \
   --restart unless-stopped \
   linuxserver/bookstack:version-v0.31.4

A mesure que la complexité d’un environnement Docker augmente, le nombre de drapeaux et de conditions nécessaires pour une configuration de conteneur fonctionnelle augmente également. La ligne de commande Docker devient alors encombrante et difficile à dépanner, surtout lorsque des configurations multi-conteneurs entrent en jeu.

Docker Compose est une façon de créer des conteneurs Docker reproductibles en utilisant un fichier de configuration plutôt que de longues commandes Docker. En utilisant un fichier de configuration structuré, les erreurs sont plus faciles à repérer et les interactions entre conteneurs sont plus faciles à définir.

Docker Compose devient rapidement indispensable lorsqu’il s’agit de gérer des dépendances entre conteneurs ou des environnements multi-conteneurs.

Docker Compose est une excellente façon de se lancer dans l’Infrastructure en tant que Code sans la complexité des systèmes distribués comme Kubernetes.

Docker Compose utilise une structure de fichier de configuration appelée YAML. YAML est similaire à JSON ou HTML en ce sens que YAML est un langage structuré et lisible par machine. YAML se concentre spécifiquement sur le fait d’être aussi lisible par les humains que possible tout en conservant cette puissance structurée.

YAML a un inconvénient où les tabulations et autres espaces vides sont significatifs et doivent être formatés correctement. VS Code fait une grande partie de ce travail difficile pour vous, c’est pourquoi vous verrez de nombreux exemples réalisés dans VS Code.

Installation de Docker Compose

Passons maintenant à la pratique. En supposant que vous êtes connecté à votre hôte Docker, il est temps d’installer Docker Compose.

Docker Compose est un package distinct de l’exécution Docker. Mais l’installation de Docker Compose installera également l’exécution Docker, vous tuerez donc deux oiseaux d’un coup !

Pour installer Docker Compose et l’exécution Docker, exécutez les deux commandes suivantes.

# mettez à jour la liste des logiciels (connue sous le nom de dépôt) puis installez docker compose
# avec toutes les dépendances nécessaires. le drapeau -y est utilisé pour ignorer la confirmation
sudo apt update -y
sudo apt install docker-compose -y
The installation command for Docker Compose

Une fois installé, vous devez maintenant créer une structure de dossier pour stocker les conteneurs.

Création d’une structure de dossier pour Docker Compose

Avant de pouvoir créer un conteneur avec Docker Compose, vous devez d’abord créer un dossier pour stocker les conteneurs. Vous ne devez pas seulement créer une structure de dossier pour stocker les conteneurs, mais vous constaterez que différentes commandes Docker sont sensibles à l’emplacement de divers fichiers de configuration ; Docker Compose ne fait pas exception.

Le composant le plus important de Docker Compose est son fichier de configuration appelé docker-compose.yaml. Ce fichier de configuration, comme expliqué ci-dessus, indique comment le moteur Docker doit construire un conteneur.

Lorsque vous exécutez Docker Compose, la commande recherchera son fichier de configuration dans le même dossier que la commande est exécutée. En raison de cette exigence, il est toujours préférable de créer un dossier séparé lors de l’exécution de Docker Compose.

Il ne peut y avoir qu’un seul fichier de configuration Docker Compose par dossier.

Pour démontrer la création d’un conteneur Docker avec Docker Compose, créez d’abord une structure de dossier pour stocker le futur conteneur et son fichier de configuration en utilisant un petit serveur de fichiers appelé Caddy.

Caddy est un serveur de fichiers, similaire à apache httpd ou nginx, mais écrit en langage Go. Caddy est spécifiquement conçu pour être facile à utiliser (et générera ou servira automatiquement un fichier index.html) sans configuration. Cette combinaison fait de Caddy un bon choix pour les débutants.

En supposant que vous soyez connecté à votre hôte Docker, créez la structure de dossiers comme suit:

  1. Dans votre répertoire personnel, créez un dossier appelé containers. Ce dossier sera un bon espace réservé pour ce conteneur et d’autres.
  2. A l’intérieur du dossier containers, créez un sous-dossier appelé caddy. Ce dossier contiendra le fichier de configuration Docker Compose et le conteneur Caddy lui-même.
  3. Enfin, à l’intérieur du dossier du conteneur, caddy, créez un fichier texte vierge appelé docker-compose.yaml qui deviendra le fichier de configuration Docker Compose.

Avec la structure de dossiers et le fichier de configuration Docker Compose créés, vous pouvez maintenant commencer à remplir ce fichier de configuration avec une configuration Docker Compose.

Création d’un fichier de configuration Docker Compose

Sous sa forme la plus basique, un fichier docker-compose.yaml pour le conteneur Caddy ressemble à ce qui suit. Dans votre éditeur de texte Linux préféré ou avec VS Code, copiez et collez le code ci-dessous dans le fichier de configuration Docker Compose créé précédemment.

version: "3.7"
services:
  caddy:
    container_name: "caddy"
    image: "caddy:latest"
    ports:
      - "80:80"

Passons en revue chacune des options affichées:

  • La version spécifie la version du fichier docker-compose. Chaque nouvelle définition de Docker Compose inclut des modifications majeures de la spécification. Par conséquent, la version est importante pour que Docker Compose puisse savoir quelles fonctionnalités il doit utiliser. La version 3.7 est la dernière version prise en charge par Ubuntu 20.04.1 LTS.

La spécification complète de Docker Compose 3.x peut être trouvée ici. La documentation liée mentionne chaque option que vous pouvez utiliser dans Docker Compose

  • services contient les spécifications des conteneurs réels. Vous pouvez définir plusieurs conteneurs dans cette section.
  • caddy est le nom du premier conteneur (c’est uniquement à titre de référence).
  • container_name définit le nom réel donné au conteneur par Docker et doit être unique.
  • image est le nom de l’image. Dans ce cas, caddy de Docker Hub est défini. Le nom ou le numéro après le tag séparé par un deux-points est la version.

Mappage de port

Cette dernière option mérite une mention spéciale :

ports:
  - "80:80"

Dans Docker Compose, la directive ports vous permet de définir une ou plusieurs correspondances entre l’hôte et le conteneur. Par exemple, ci-dessus, vous avez fait correspondre le port 80 de l’hôte au port 80 du conteneur. Cependant, vous n’êtes pas obligé de faire correspondre le numéro de port. L’exemple ci-dessous fait correspondre le port 8800 de l’hôte au port 80 du conteneur.

ports:
  - "8800:80"

Vous pouvez également définir plusieurs ports comme ci-dessous.

ports:
  - "80:80"
  - "443:443"

Ainsi, les ports 80 et 443 seraient mappés sur l’hôte (une configuration courante pour les serveurs web, pour servir à la fois HTTP et HTTPS).

Le créateur de l’image Docker définit les ports disponibles au moment de la création. Assurez-vous de consulter la documentation de l’image avec laquelle vous travaillez sur Docker Hub ou le site Web du mainteneur pour connaître les ports mappables. Il est inutile de mapper un port s’il n’est pas utilisé !

Avec cela à l’esprit, regardons comment exécuter réellement le conteneur.

Exécution du conteneur

À ce stade, vous devriez avoir le fichier docker-compose.yaml dans votre dossier ~\containers\caddy. C’est maintenant le moment de créer et de démarrer le conteneur Caddy.

Sur votre terminal, exécutez la commande suivante qui démarrera les conteneurs Docker définis dans le fichier docker-compose.yaml.

# Cette commande doit être exécutée dans le même dossier que le fichier. L'option -d exécute
# la commande en arrière-plan (*detached*) et démarrera le conteneur en arrière-plan
sudo docker-compose up -d

Vous remarquerez peut-être que vous n’avez pas eu à spécifier l’emplacement du fichier docker-compose.yaml lors de l’exécution de la commande sudo docker-compose up -d. Docker Compose s’attend à ce que vous exécutiez toutes les commandes à l’intérieur du dossier qui contient le fichier docker-compose.yaml, car de nombreuses commandes sont relatives à ce dossier.

Maintenant, vérifiez que le conteneur est en cours d’exécution en naviguant vers http://<votre adresse IP>. Ce guide utilise http://homelab-docker à titre de référence.

Vous pouvez voir ce traitement se dérouler dans VS Code pendant que vous êtes connecté en SSH à l’hôte Docker dans l’animation ci-dessous:

Demonstrating a container created with Docker Compose

Succès ! Vous avez maintenant utilisé avec succès Docker Compose pour démarrer un conteneur à partir d’un fichier de configuration. Avec cette première étape importante franchie, examinons comment vous gérez l’état de votre conteneur.

Commandes pour gérer les conteneurs détachés

Dans la section précédente, vous avez démarré le conteneur caddy en utilisant le drapeau -d. Ce faisant, un conteneur a été exécuté dans un état détaché. Lorsqu’un conteneur est dans un état détaché, il continuera à s’exécuter en arrière-plan. Cependant, cela pose un problème : comment gérez-vous ce conteneur si vous n’avez plus un contrôle direct ?

Pour résoudre ce problème, Docker Compose dispose d’une série de commandes qui permettront de gérer les conteneurs démarrés à l’aide d’un fichier docker-compose.yaml:

  • docker-compose restart est utilisé pour redémarrer un conteneur qui est actuellement en cours d’exécution. Ceci est différent de l’exécution réelle de docker-compose up -d. La commande de redémarrage redémarrera simplement un conteneur existant, réexécutera la commande docker-compose up -d et recréera le conteneur à partir de zéro (si le fichier de configuration a été modifié).
  • docker-compose stop arrêtera un conteneur en cours d’exécution sans détruire le conteneur. De même, docker-compose start redémarrera le conteneur.
  • docker-compose down arrêtera les conteneurs en cours d’exécution et les détruira également. C’est là que l’utilisation des montages de volumes prend tout son sens (en savoir plus ci-dessous).
  • docker-compose pull récupérera la version actuelle de l’image Docker (ou des images) depuis le référentiel. Si vous utilisez l’étiquette latest, vous pouvez suivre avec docker-compose down && sudo docker-compose up -d pour remplacer le conteneur par la dernière version. L’utilisation de docker-compose pull est un moyen pratique de mettre à jour rapidement les conteneurs avec un temps d’arrêt minimal.
  • docker-compose logs affichera les journaux du conteneur en cours d’exécution (ou arrêté). Vous pouvez également cibler des conteneurs individuels (s’il y a plusieurs conteneurs définis dans le fichier de composition) avec docker-compose logs <nom du conteneur>.

A full list of docker-compose commands can be seen by running docker-compose with no additional arguments or referenced here in the documentation.

Maintenant que vous avez un conteneur en cours d’exécution, examinons l’utilisation de contenu enregistré localement sur votre machine.

Création de montages de volumes dans Docker Compose

Les montages de liaison sont la manière dont Docker associe les données utilisateur importantes au stockage local sur votre serveur. Pour commencer, générez du contenu à héberger dans le conteneur :

  1. Sur l’hôte Docker, à l’intérieur du dossier ~/containers/caddy, créez un nouveau dossier appelé files.

2. Créez un nouveau fichier appelé index.html à l’intérieur du dossier ~/containers/caddy qui ressemble à ce qui suit. Cela sera la page principale que le serveur web Caddy va servir.

<body><h2>hello world!</h2></body>

3. Modifiez votre fichier de configuration Docker Compose pour qu’il ressemble à ce qui suit. L’exemple ci-dessous ajoute la section volumes et pointe un montage de liaison vers le dossier files qui vient d’être créé afin de le rendre disponible pour le conteneur.

version: "3.7" services: caddy: container_name: "caddy" image: "caddy:latest" ports: - "80:80" volumes: #le ./ fait référence à un dossier relatif au fichier docker-compose - "./files:/usr/share/caddy"

4. Exécutez à nouveau la commande docker-compose up -d. Docker Compose reconnaîtra maintenant que le fichier a été modifié et recréera votre conteneur.

5. Accédez à la page du conteneur avec un navigateur et vous devriez maintenant voir qu’il sert la page « Hello World! ».

Vous pouvez voir ce qui suit dans l’animation ci-dessous :

Creating a bind mount using Docker Compose

Vous hébergez maintenant du contenu stocké localement sur votre machine ! Cependant, que faire si votre contenu se trouve sur une source externe comme un partage réseau ?

Utilisation de Docker Compose avec les volumes Docker.

Une fois que vous avez créé un simple conteneur avec Docker Compose, vous aurez probablement besoin que ce conteneur accède à des fichiers ailleurs, peut-être sur un partage réseau. Si tel est le cas, vous pouvez configurer le conteneur pour utiliser des volumes Docker directement dans votre fichier de configuration Docker Compose.

À titre d’exemple, ce guide va créer un serveur partage de fichiers en réseau (NFS) sur l’hôte Docker. Servir du contenu local en tant que montage NFS n’a aucune utilité pratique en dehors de la démonstration. Si vous montez un volume NFS, il proviendra généralement d’une source externe comme un NAS ou un serveur distant.

Configurer un partage NFS

Si vous n’avez pas déjà configuré un partage NFS, créez-en un maintenant sur l’hôte Docker pour ce tutoriel. Pour ce faire :

  1. Installez le package serveur NFS en exécutant la commande apt install nfs-kernel-server -y.

2. Ajoutez le conteneur en tant qu’exportation NFS (similaire à un partage CIFS Windows) en exécutant ce qui suit.

# Ajoutez une ligne au fichier de configuration /etc/exports pour créer un partage NFS pour # /home/homelab/containers. Ce partage est uniquement accessible depuis localhost (pour # empêcher les autres ordinateurs d'y accéder) echo '/home/homelab/containers localhost(rw,sync,no_root_squash,no_subtree_check)' | sudo tee -a /etc/exports # Redémarrez le serveur NFS avec la nouvelle configuration sudo systemctl restart nfs-kernel-server

3. Vérifiez maintenant que l’hôte expose le partage NFS en exécutant la commande showmount -e localhost. Cette commande affichera tous les partages NFS actuellement exposés et les personnes qui y ont accès.

Sur la capture d’écran ci-dessous, vous pouvez voir que /home/homelab/containers est exposé, mais uniquement à l’ordinateur local (qui est le même serveur exécutant l’hôte Docker).

Creating a NFS share in Ubuntu 20.04

Si vous voyez le dossier /home/<nom_utilisateur>/containers dans la sortie, le partage NFS est configuré.

Définition d’un volume nommé Docker

Une fois que vous avez créé le partage NFS, vous devez maintenant indiquer à Docker comment accéder à ce partage. À l’aide de Docker Compose, vous pouvez le faire en définissant un volume nommé dans le fichier de configuration Docker Compose.

A named volume is a way for Docker to abstract network-based file shares. Network file sharing comes in all sorts of shapes and sizes these days: CIFS (windows) shares, NFS (Linux) shares, AWS S3 Buckets, and more. By creating a Named Volume, Docker does the hard part of figuring out how to talk to the network share and lets the container just treat the share as if it is local storage.

Pour créer un volume nommé :

  1. Ouvrez le fichier de configuration Docker Compose (docker-compose.yaml). Si vous suivez le tutoriel, le fichier devrait se trouver dans le dossier ~/containers/caddy.

2. À l’intérieur du fichier de configuration Docker Compose, ajoutez une section volumes après la section services. Votre fichier de configuration devrait ressembler à ce qui suit. La section volumes crée un volume nommé MyWebsite. À l’intérieur de ce volume nommé, les paramètres nécessaires (tels que l’adresse IP, les paramètres NFS et le chemin d’accès) sont spécifiés. Le paramètre volumes de la section services est également modifié pour pointer vers le volume nommé au lieu d’un dossier local.

version: "3.7"
 services:
   caddy:
     container_name: "caddy"
     image: "caddy:latest"
     ports:
       - "80:80"
     volumes:
       - "MyWebsite:/usr/share/caddy"
 volumes:
   MyWebsite:
     driver_opts:
       type: "nfs"
       o: "addr=localhost,nolock,soft,rw"
       device: ":/home/homelab/containers/caddy/files"

3. Une fois que vous avez défini le volume nommé pointant vers le partage NFS dans le fichier de configuration Docker Compose, exécutez la commande docker-compose up -d pour créer et démarrer le conteneur. Si tout se passe bien, le conteneur et le site web devraient redémarrer.

Setting NFS client settings within Docker Compose in VS Code

4. Accédez à nouveau à la page du conteneur. Le contenu du fichier index.html devrait apparaître comme s’il était monté localement. Cependant, ce fichier est monté via le serveur NFS configuré sur le réseau.

Demonstrating access to the index.html file through an NFS share in Docker

Maintenant que vous pouvez monter des volumes Docker externes dans Docker Compose, vous pouvez maintenant intégrer toutes sortes de stockage réseau dans vos conteneurs. Cependant, Docker Compose peut faire plus que simplement définir des conteneurs ou des volumes uniques. Plongeons dans des scénarios plus complexes, avec plusieurs conteneurs.

Ce tutoriel n’utilisera plus le conteneur caddy, vous pouvez donc supprimer le conteneur à l’aide de la commande docker-compose down.

Définition de plusieurs conteneurs dans Docker Compose

La plupart des conteneurs Docker ne fonctionnent pas isolément. Les conteneurs Docker ont généralement des dépendances de service telles que des bases de données ou des services web distincts qui communiquent via une API.

En utilisant Docker Compose, vous pouvez regrouper des conteneurs définis dans un seul fichier. En définissant plusieurs conteneurs dans un seul fichier, les conteneurs peuvent communiquer entre les services dépendants et simplifier l’organisation de configurations de conteneurs complexes.

Pour illustrer un tel scénario, configurons une application wiki populaire appelée BookStack.

BookStack est un logiciel wiki populaire connu pour sa facilité d’utilisation et sa disposition hiérarchique (par opposition à une disposition plate, comme mediawiki).

BookStack, comme de nombreuses applications web, nécessite une base de données distincte pour fonctionner correctement, ainsi que les informations nécessaires pour communiquer avec la base de données. La mise en place d’une telle situation est l’un des points forts de Docker Compose.

Créez le fichier de configuration Docker Compose

BookStack n’a pas d’image Docker maintenue en interne, cependant, linuxserver.io maintient une image réputée sur le Docker Hub au nom de BookStack. Bien que la documentation sur le site de Docker Hub propose un fichier de configuration Docker Compose recommandé, ce tutoriel va créer un nouveau fichier de configuration tout en expliquant les concepts.

Sur l’hôte Docker:

  1. Tout d’abord, créez un dossier pour BookStack. Si vous avez suivi les tutoriels de la section précédente, vous devriez avoir un dossier ~/containers. Créez un dossier appelé bookstack à l’intérieur.

2. Ensuite, créez un fichier de configuration Docker Compose vide appelé docker-compose.yaml à l’intérieur du dossier bookstack.

Creating the folder structure for Bookstack in VS Code

3. Ouvrez maintenant le fichier de configuration Docker Compose et définissez deux conteneurs : le conteneur bookstack et le conteneur bookstack_db (mariadb).

version: "3.7"
 services:
   bookstack:
     container_name: "bookstack"
     image: "ghcr.io/linuxserver/bookstack"
     ports:
       - "8080:80"
     volumes:
       - "./files:/usr/share/caddy"
     depends_on:
       - "bookstack_db"
   bookstack_db:
     container_name: "bookstack_db"
     image: "mariadb"
     volumes:
       - "./db:/var/lib/mysql"

Jusqu’à présent, ce fichier docker-compose.yaml utilise principalement des concepts déjà présentés : Vous avez deux services (bookstack et bookstack_db), tous les deux avec des images et des bind mounts. Le conteneur bookstack a un mappage de port du port hôte 8080 vers le port interne 80.

Étant donné le coût extrêmement faible des conteneurs Docker, il est courant de définir un conteneur de base de données séparé pour chaque application web. Cela permet une plus grande séparation des tâches. C’est une différence nette par rapport aux configurations de base de données traditionnelles, où une seule installation de base de données peut desservir des centaines d’applications web.

Une nouvelle option que vous pouvez voir dans le fichier ci-dessus est la commande depends_on. Cette commande indique à Docker l’ordre dans lequel les conteneurs doivent démarrer. En définissant la commande depends_on, Docker sait que le conteneur bookstack_db doit démarrer en premier.

Mise en place de la communication entre les conteneurs à l’aide de variables d’environnement

Ce fichier de configuration créé dans la dernière section n’est pas encore complet. Bien que vous ayez défini deux services (conteneurs), ils ne se parlent pas ! Le conteneur bookstack ne sait pas comment communiquer avec le conteneur bookstack_db. Résolvons cela en utilisant des variables d’environnement.

Les variables d’environnement sont le moyen le plus courant de fournir des variables aux conteneurs Docker. Ce sont des variables fournies lors de l’exécution (ou définies dans le fichier de configuration docker-compose.yaml) pour fournir des informations sur ce que le conteneur doit faire.

Les variables d’environnement sont définies par la personne qui crée l’image Docker. Elles seront différentes selon l’image Docker que vous utilisez, et vous devez vous référer à la documentation du créateur concernant les variables d’environnement à utiliser.

Il existe deux méthodes pour définir des variables d’environnement : directement dans le fichier docker-compose.yaml lui-même ou en tant que fichier séparé.

A separate file is, typically, the recommended method, especially if variables contain sensitive data such as passwords. A docker-compose.yaml file is designed to be shared or even uploaded to a public-facing GitHub repo. Having a separate file for sensitive data reduces the chance of an accidental security breach.

Sur l’hôte Docker, créez maintenant deux variables d’environnement ; une pour le conteneur bookstack et une pour le conteneur bookstack_db.

  1. Créez un nouveau fichier dans le dossier ~/containers/bookstack appelé bookstack.env avec le contenu suivant :
APP_URL is the IP address or hostname of your server. This article is using homelab-docker
 APP_URL=http://homelab-docker:8080
 DB_HOST is the container name you gave your container
 DB_HOST=bookstack_db
 DB_USER is defined in the bookstack_DB environment file
 DB_USER=bookstack_user
 DB_PASS is also defined in the bookstack_DB environment file
 DB_PASS=MySecurePassword
 DB_DATABASE is the name of the database within mariadb
 DB_DATABASE=bookstack

2. Créez un nouveau fichier dans le dossier ~/containers/bookstack appelé bookstack_db.env et incluez le contenu suivant :

The root password for our database, keep it secret, keep it safe
 MYSQL_ROOT_PASSWORD=MySecureRootPassword
 The database bookstack will be using
 MYSQL_DATABASE=bookstack
 the user bookstack will be using
 MYSQL_USER=bookstack_user
 the password bookstack will be using
 MYSQL_PASSWORD=MySecurePassword

3. Comme bonne pratique, assurez-vous maintenant que les fichiers env ne sont pas lisibles par d’autres utilisateurs.

chmod 600 bookstack.env bookstack_db.env

Vous devriez modifier les droits d’accès en lecture car les fichiers bookstack.env et bookstack_db.env contiennent des données sensibles.

4. Mettez à jour le fichier Docker Compose ~/containers/bookstack/docker-compose.yaml pour faire référence à ces deux fichiers d’environnement comme indiqué ci-dessous.

version: "3.7"
 services:
   bookstack:
     container_name: "bookstack"
     image: "ghcr.io/linuxserver/bookstack"
     ports:
       - "8080:80"
     volumes:
       - "./files:/usr/share/caddy"
     depends_on:
       - "bookstack_db"
     env_file:
       - "./bookstack.env"
   bookstack_db:
     container_name: "bookstack_db"
     image: "mariadb"
     volumes:
       - "./db:/var/lib/mysql"
     env_file:
       - "./bookstack_db.env"

5. Maintenant, lancez les conteneurs bookstack et bookstack_db en utilisant Docker Compose.

sudo docker-compose up -d

Vous pouvez voir chacune des étapes mentionnées dans cette section réalisées dans VS Code ci-dessous.

Setting up environment variables and the Docker Compose file with VS Code

Suivi des journaux Docker Compose

Le moteur Docker fonctionne avec Docker Compose pour effectuer de nombreuses tâches différentes en arrière-plan. Pouvoir surveiller ce qui se passe, surtout lorsqu’on travaille avec plusieurs conteneurs à la fois, est utile.

Pour surveiller le conteneur bookstack, par exemple, utilisez la commande logs. Dans ce tutoriel, une fois que vous voyez les journaux afficher [services.d] done, vous pouvez accéder à l’URL de bookstack.

sudo docker-compose logs bookstack
Using the docker-compose logs command
The bookstack welcome screen. Default login is [email protected]/password

À ce stade, vous devriez avoir un wiki entièrement fonctionnel fonctionnant dans son propre conteneur, avec sa propre base de données, entièrement dans Docker !

Tant que vous avez les dossiers bookstack et bookstack_db, vous pouvez recréer votre environnement bookstack à partir de zéro.

Docker Compose et réseau

Jusqu’à présent, vous n’avez pas appris grand-chose sur la communication et l’aspect réseau de la façon dont les conteneurs travaillent ensemble. Changeons cela.

Lorsque vous créez plusieurs conteneurs dans un seul fichier docker-compose.yaml, comme vous l’avez fait dans les sections précédentes, ils sont tous assignés au même réseau (généralement appelé nom-du-dossier-parent_default).

Vous pouvez voir le réseau créé pour les conteneurs lorsque vous exécutez docker-compose up -d comme indiqué ci-dessous.

The default network created with docker-compose comes up

Lorsque tous les conteneurs sont assignés au même réseau, Docker crée des entrées DNS pour eux en interne. C’est pourquoi, dans l’exemple précédent, vous avez référencé votre base de données en tant que bookstack_db dans les variables d’environnement. Ce nom bookstack_db est en réalité une entrée DNS qui pointe vers l’adresse IP du conteneur de la base de données.

Vous n’avez pas non plus à vous fier à Docker Compose pour générer automatiquement des réseaux pour vous. Vous pouvez définir manuellement des réseaux internes ou externes. La définition manuelle des réseaux est idéale lorsque vous avez un conteneur qui doit communiquer avec un autre conteneur dans un fichier docker-compose.yaml distinct. Vous pouvez exposer les ports, ou vous pouvez créer un réseau auquel ils peuvent tous deux se joindre !

Notez que lorsque vous commencez à définir explicitement des réseaux, vous devez également définir explicitement le réseau par défaut. Docker Compose cessera de créer automatiquement ce réseau une fois que vous commencerez à définir les réseaux

Modifiez maintenant le fichier docker-compose.yaml de BookStack pour inclure un réseau créé à l’extérieur.

  1. Créez le réseau externe avec la commande docker network create my_external_network.

2. Définissez le réseau externe dans le fichier docker-compose.yaml:

version: "3.7"
 services:
   bookstack:
     container_name: "bookstack"
     image: "ghcr.io/linuxserver/bookstack"
     ports:
       - "8080:80"
     volumes:
       - "./files:/usr/share/caddy"
     depends_on:
       - "bookstack_db"
     env_file:
       - "./bookstack.env"
     networks:
       - "my_external_network"
       - "bookstack_default"
   bookstack_db:
     container_name: "bookstack_db"
     image: "mariadb"
     volumes:
       - "./db:/var/lib/mysql"
     env_file:
       - "./bookstack_db.env"
     networks:
       - "bookstack_default"
 networks:
   bookstack_default:
   my_external_network:
     external: true

3. Exécutez la commande docker-compose up -d pour recréer les conteneurs. Vos deux conteneurs sont maintenant connectés à deux réseaux comme indiqué ci-dessous.

A highlight of the networks defined within a docker-compose file

Le conteneur BookStack est maintenant également connecté à un réseau défini de manière externe. Cela vous permet de créer un autre conteneur qui transforme le trafic HTTP de BookStack en HTTPS avant de quitter Docker (appelé un reverse-proxy).

Définition d’un utilisateur spécifique pour exécuter un conteneur.

Par défaut, tous les conteneurs Docker s’exécutent en tant qu’utilisateur root isolé. Cela équivaut à exécuter une machine virtuelle connectée en tant qu’utilisateur Administrateur par défaut. Bien que cela généralement ne pose pas de problème, il existe des problèmes de sécurité si le sandbox est compromis.

Le problème lié à l’exécution en tant que root concerne également les autorisations de fichier. Vous pouvez constater que si vous essayez de supprimer le dossier db à l’intérieur du dossier bookstack, vous ne pouvez pas le faire ; le contenu appartient à root.

Alors que la plupart des images n’apprécient pas l’exécution en tant qu’utilisateur non-root, les images de linuxserver.io en particulier offrent une variable d’environnement pour définir l’utilisateur qui s’exécute à l’intérieur du conteneur. Vous pouvez le faire en ajoutant UID=1000 et GID=1000 dans la configuration de bookstack.env.

1000:1000 est l’ID d’utilisateur et de groupe par défaut pour le premier utilisateur dans Ubuntu (ce qui peut ne pas être votre cas). Vous pouvez en savoir plus sur les ID utilisateur et les ID de groupe dans Related: A Windows Guy in a Linux World: Users and File Permissions)

Vous pouvez également forcer un UID et un GID en utilisant le paramètre user dans docker-compose, mais cela n’est pas recommandé car la plupart des conteneurs ne se comportent pas bien lorsqu’ils sont forcés à utiliser un utilisateur différent

Définir la stratégie de redémarrage

Si vous souhaitez que les conteneurs construits avec Docker Compose redémarrent en cas de défaillance, utilisez la politique de redémarrage en ajoutant un paramètre restart: <option> dans les paramètres du conteneur dans docker-compose.yaml.

restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

L’ajout de ce paramètre entraînera le redémarrage automatique des conteneurs en cas de défaillance, ce qui permettra de maintenir la disponibilité en cas de problèmes de puissance inattendus.

Configuration manuelle des entrées DNS pour les conteneurs

Tout comme Windows et Linux, Docker dispose également d’un « fichier hosts ». En utilisant le paramètre extra_hosts dans un fichier de configuration, vous pouvez forcer un hôte à résoudre une adresse IP spécifique. Cela peut être utile lorsque vous avez des contraintes DNS, telles que DNS divisé ou un serveur de test avec lequel vous souhaitez interagir temporairement.

extra_hosts:
  - "somehost:x.x.x.x"
  - "otherhost:x.x.x.x"

Exécution de commandes

Une fois le conteneur démarré, vous pouvez exécuter des commandes à l’intérieur du conteneur à l’aide de la commande docker-compose run. Par exemple, peut-être souhaitez-vous démarrer un terminal Bash à l’intérieur de votre conteneur bookstack. Pour cela, vous exécuteriez la commande ci-dessous.

docker-compose run web bash

Conclusion

À ce stade, vous devriez disposer des informations nécessaires pour suivre la plupart des tutoriels docker-compose disponibles sur le web. Cette connaissance peut considérablement élargir vos capacités pour vous lancer dans le monde de Docker et la construction d’applications web en tant qu’Infrastructure as Code.

Source:
https://adamtheautomator.com/docker-compose-tutorial/