Lorsque vous utilisez Docker pour conteneuriser vos applications, il est courant d'exécuter chaque composant de l'application dans un conteneur séparé. Par exemple, un site Web peut avoir un serveur Web, une application et une base de données, chacun s'exécutant dans son propre conteneur.
Configurer les conteneurs pour communiquer entre eux et avec la machine hôte peut être un défi. Ce guide utilisera un exemple d'application simple pour démontrer les bases de la communication avec le conteneur Docker. L'application consistera en une application Node.js qui lit les données d'une base de données PostgreSQL.
Avant de commencer
Installer Docker CE
Vous aurez besoin d'un Linode avec Docker CE installé pour suivre les étapes de ce guide.
Pour installer Docker CE (Community Edition), suivez les instructions de l'un des guides ci-dessous :
-
Installation et utilisation de Docker sur Ubuntu et Debian
-
Installation et utilisation de Docker sur CentOS et Fedora
Pour obtenir des instructions complètes sur encore plus de distributions Linux, consultez la section Install Docker Engine de la documentation officielle de Docker.
Exemple d'application Node.js
L'exemple d'application utilisé tout au long de ce guide sera une simple application Node.js qui lira "Hello world" à partir d'une base de données PostgreSQL et l'imprimera sur la console. Dans cette section, vous allez créer et tester l'application sur votre Linode sans utiliser de conteneurs.
Installer et configurer PostgreSQL
-
Mettez à jour votre système :
sudo apt update && sudo apt upgrade
-
Installez PostGreSQL :
sudo apt install postgresql postgresql-contrib
-
Changer le
postgres
mot de passe de l'utilisateur :sudo passwd postgres
-
Définir un mot de passe pour le
postgres
utilisateur de la base de données :su - postgres psql -d template1 -c "ALTER USER postgres WITH PASSWORD 'newpassword';"
-
Créez une base de données pour l'exemple d'application et connectez-vous à celle-ci :
createdb nodejs psql nodejs
-
Ajoutez "Hello world" à la base de données :
nodejs=# CREATE TABLE hello (message varchar); nodejs=# INSERT INTO hello VALUES ('Hello world'); nodejs=# \q
-
Créez un vidage de la base de données pour une utilisation ultérieure :
pg_dumpall > backup.sql
-
Déconnectez-vous en tant que
postgres
Utilisateur Linux :exit
-
Copiez le vidage des données dans votre répertoire personnel :
sudo cp /var/lib/postgresql/backup.sql ~/.
-
Puisque vous vous connecterez à cette base de données à partir d'un conteneur (qui aura une adresse IP autre que
locahost
), vous devrez modifier le fichier de configuration PostgreSQL pour autoriser les connexions à partir d'adresses distantes. Ouvrez/etc/postgresql/9.5/main/postgresql.conf
dans un éditeur de texte. Décommentez leslisten_addresses
et réglez-le sur '*' :- Fichier :/ etc/postgresql/9.5/main/postgresql.conf
1 2 3 4 5 6 7
#------------------------------------------------------------------------------ # CONNECTIONS AND AUTHENTICATION #------------------------------------------------------------------------------ # - Connection Settings - listen_addresses = '*' # what IP address(es) to listen on;
-
Activer et démarrer le
postgresql
service :sudo systemctl enable postgresql sudo systemctl start postgresql
Créer une application Hello World
-
Installer Node et NPM :
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install nodejs
-
Accédez au répertoire personnel et créez un répertoire :
cd mkdir app && cd app
-
À l'aide d'un éditeur de texte, créez
app.js
et ajoutez le contenu suivant :- Fichier :app .js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
const { Client } = require('pg') const client = new Client({ user: 'postgres', host: 'localhost', database: 'nodejs', password: 'newpassword', port: 5432 }) client.connect() client.query('SELECT * FROM hello', (err, res) => { console.log(res.rows[0].message) client.end() })
Cette application utilise le
pg
Module NPM (node-postgres) pour se connecter à la base de données créée dans la section précédente. Il interroge ensuite la table "hello" (qui renvoie le message "Hello world") et enregistre la réponse dans la console. Remplacez'newpassword'
avec lepostgres
mot de passe de l'utilisateur de la base de données que vous avez défini dans la section précédente.Remarque Le
pg
module peut également utiliser des variables d'environnement pour configurer la connexion client. Il s'agit de l'option recommandée pour les applications de production. En savoir plus sur les variables d'environnement dans la documentation de thenode-postgres. -
Installez le
pg
modules :npm install pg
-
Testez l'application :
node app.js
Si la base de données est configurée correctement, "Hello world" s'affichera sur la console.
Connecter le conteneur à l'hôte Docker
Cette section illustre un cas d'utilisation dans lequel l'application Node.js est exécutée à partir d'un conteneur Docker et se connecte à une base de données qui s'exécute sur l'hôte Docker.
Configurer le conteneur Docker
-
Retournez à votre répertoire personnel :
cd
-
Créez un Dockerfile pour exécuter l'application Node.js :
- Fichier :Dockerfile
1 2 3 4 5 6 7
FROM debian RUN apt update -y && apt install -y gnupg curl RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && apt install -y nodejs COPY app/ /home/ ENTRYPOINT tail -F /dev/null
-
L'image construite à partir de ce Dockerfile copiera le
app/
répertoire vers la nouvelle image. Modifierapp.js
pour permettre à l'application de se connecter à ladatabase
hôte au lieu delocalhost
:- Fichier :app /app.js
1 2 3 4 5 6 7
const client = new Client({ user: 'postgres', host: 'database', database: 'nodejs', password: 'newpassword', port: 5432 })
-
Créez une image à partir du Dockerfile :
docker build -t node_image .
Connecter le conteneur à la base de données
-
Docker configure automatiquement un réseau pont par défaut , accessible via le
docker0
interface réseau. Utilisezifconfig
ouip
pour afficher cette interface :ifconfig docker0
Le résultat ressemblera à ce qui suit :
L'adresse IP interne de l'hôte Docker (votre Linode) est 172.17.0.1.docker0 Link encap:Ethernet HWaddr 02:42:1e:e8:39:54 inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:1eff:fee8:3954/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:3848 errors:0 dropped:0 overruns:0 frame:0 TX packets:5084 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:246416 (246.4 KB) TX bytes:94809688 (94.8 MB)
-
Autorisez PostgreSQL à accepter les connexions de l'interface Docker. Ouvrez
/etc/postgresql/9.5/main/pg_hba.conf
dans un éditeur de texte et ajoutez la ligne suivante :- Fichier :/ etc/postgresql/9.5/main/pg_hba.conf
1
host all postgres 172.17.0.0/16 password
Étant donné que 172.17.0.1 est l'adresse IP de l'hôte Docker, tous les conteneurs de l'hôte auront une adresse IP dans la plage 172.17.0.0/16.
-
Redémarrez la base de données :
sudo systemctl restart postgresql
-
Démarrez le conteneur :
docker run -d --add-host=database:172.17.0.1 --name node_container node_image
Le
--add-host
l'option définit unedatabase
host, qui pointe vers l'adresse IP de l'hôte Docker. Déclaration de ladatabase
héberger au moment de l'exécution, plutôt que de coder en dur l'adresse IP dans l'application, permet de garder le conteneur réutilisable. -
Depuis le conteneur, utilisez
ping
pour tester la connexion à ladatabase
hébergeur :docker exec -it node_container ping database
-
Chaque conteneur Docker se voit également attribuer sa propre adresse IP à partir du bloc 172.17.0.0/16. Trouvez l'adresse IP de ce conteneur avec
ip
:docker exec -it node_container ip addr show eth0
Vous pouvez tester cette connexion en envoyant un ping à cette adresse depuis l'hôte Docker.
-
Exécutez l'application :
docker exec -it node_container node home/app.js
Si la configuration a réussi, le programme devrait afficher la sortie de la console "Hello world" comme avant.
Connecter deux conteneurs
Dans cette section, l'application et la base de données seront exécutées dans des conteneurs distincts. Vous pouvez utiliser l'image postgres officielle de Docker Hub et la charger dans le vidage SQL créé précédemment.
Attention Vous ne devez pas stocker les données de la base de données de production dans un conteneur Docker. Les conteneurs doivent être traités comme des entités éphémères :si un conteneur tombe en panne ou est redémarré de manière inattendue, toutes les données de la base de données seront perdues.
-
Arrêtez et supprimez le conteneur Node.js :
docker stop node_container docker rm node_container
-
Tirez le
postgres
image :docker pull postgres
-
Assurez-vous que votre
backup.sql
le fichier est dans votre répertoire de travail actuel, puis exécutez lepostgres
image :docker run -d -v `pwd`:/backup/ --name pg_container postgres
Le
-v
L'option monte votre répertoire de travail actuel sur/backup/
répertoire sur le nouveau conteneur. -
Le nouveau conteneur démarrera automatiquement la base de données postgres et créera l'utilisateur postgres. Entrez dans le conteneur et chargez le vidage SQL :
docker exec -it pg_container bash cd backup psql -U postgres -f backup.sql postgres exit
-
Exécutez à nouveau l'image du nœud. Cette fois, au lieu de
--add-host
, utilisez le--link
option pour connecter le conteneur à pg_container :docker run -d --name node_container --link=pg_container:database node_image
Cela liera le
pg_container
sous le nom d'hôtedatabase
. -
Ouvrez
/etc/hosts
dans node_container pour confirmer que le lien a bien été fait :docker exec -it node_container cat /etc/hosts
Il devrait y avoir une ligne semblable à la suivante :
- Fichier :/ etc/hôtes
172.17.0.2 database pg_container
Cela montre que
pg_container
a été attribué à l'adresse IP 172.17.0.2, et est lié à ce conteneur via le nom d'hôtedatabase
, comme prévu. -
Étant donné que l'application Node.js attend toujours de se connecter à une base de données PostgreSQL sur la
database
hôte, aucune autre modification n'est nécessaire. Vous devriez pouvoir exécuter l'application comme avant :docker exec -it node_container node home/app.js
Utiliser Docker Compose
Utilisation du --link
ou --host
les options à chaque fois que vous lancez vos conteneurs peuvent être fastidieuses. Si votre serveur ou l'un des conteneurs tombe en panne, ils doivent être reconnectés manuellement. Ce n'est pas une situation idéale pour toute application nécessitant une disponibilité constante. Heureusement, Docker fournit Docker Compose pour gérer plusieurs conteneurs et les lier automatiquement lors de leur lancement. Cette section utilisera Docker Compose pour reproduire les résultats de la section précédente.
Remarque Pour une explication plus complète de Docker Compose et comment écrire docker-compose.yml
fichiers de configuration, consultez notre guide complet Docker Compose.
-
Installez Docker Compose :
sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
-
Dans le même répertoire que votre Dockerfile, créez un
docker-compose.yml
fichier avec le contenu suivant :- Fichier :menu fixe -compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
version: '3' services: database: image: postgres container_name: pg_container volumes: - pgdata:/var/lib/postgresql/data app: build: . container_name: node_container links: - database environment: - PGPASSWORD=newpassword - PGUSER=postgres - PGDATABASE=nodejs - PGHOST=database - PGPORT=5432 depends_on: - database volumes: pgdata: {}
Lorsque vous exécutez Docker Compose avec ce fichier, il créera le
pg_container
etnode_container
de la section précédente. Comme auparavant, le conteneur de la base de données utilisera l'image PostgreSQL officielle, tandis que le conteneur de l'application sera construit à partir de votre Dockerfile. Leslinks
l'entrée a la même fonction que le--link
option dans lerun
commande utilisée précédemment. -
Docker Compose vous permet également de configurer des valeurs d'environnement, de sorte que vous pouvez simplifier l'application pour les utiliser plutôt que d'avoir les valeurs codées en dur. Modifier
app.js
pour supprimer ces valeurs :- Fichier :app .js
1 2 3 4 5 6 7 8 9 10 11
const express = require('express') const { Client } = require('pg') const client = new Client() client.connect() client.query('SELECT * FROM hello', (err, res) => { console.log(res.rows[0].message) client.end() })
-
Supprimez les conteneurs précédents :
docker rm -f node_container pg_container
-
Utilisez Docker Compose pour afficher les conteneurs :
docker-compose up -d
-
Chargez les exemples de données dans le nouveau conteneur :
docker cp backup.sql pg_container:/ docker exec -it pg_container psql -U postgres -f backup.sql postgres
-
Exécutez
app.js
depuis le conteneur de l'application :docker exec -it node_container node home/app.js
L'application devrait fonctionner comme avant.
Conclusion
Par défaut, Docker attribue automatiquement une adresse IP à chaque conteneur et à l'hôte Docker. Vous pouvez connecter manuellement des services entre conteneurs en utilisant ces adresses (en supposant que votre pare-feu autorise la connexion).
Cependant, Docker fournit également un certain nombre de wrappers pratiques autour de ces connexions pour vous aider à accélérer et à simplifier le processus de connexion. Vous pouvez connecter votre hôte Docker à un conteneur avec un nom d'hôte unique ou lier directement deux conteneurs. L'utilisation de Docker Compose peut encore simplifier ce processus en vous permettant de déclarer des connexions dans le docker-compose.yml
fichier afin qu'ils soient établis automatiquement lors de la montée des conteneurs.
Il existe d'autres options de connexion qui n'ont pas été couvertes dans ce guide. Par exemple, vous pouvez exécuter un conteneur en utilisant --net="host"
, qui partagera la pile réseau de ce conteneur avec l'hôte Docker :localhost
sur le conteneur pointera vers localhost
sur l'hôte Docker. Vous pouvez également exposer des ports sur chaque conteneur Docker ou configurer le réseau de pont par défaut pour plus de flexibilité. Pour une discussion plus approfondie de ces options, consultez les liens dans la section Plus d'informations ci-dessous.
Plus d'informations
Vous pouvez consulter les ressources suivantes pour plus d'informations sur ce sujet. Bien que ceux-ci soient fournis dans l'espoir qu'ils seront utiles, veuillez noter que nous ne pouvons pas garantir l'exactitude ou l'actualité des documents hébergés en externe.
- Docker :comprendre la communication des conteneurs
- Lier des conteneurs
- Connecter des conteneurs