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
postgresmot de passe de l'utilisateur :sudo passwd postgres -
Définir un mot de passe pour le
postgresutilisateur 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
postgresUtilisateur 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.confdans un éditeur de texte. Décommentez leslisten_addresseset 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
postgresqlservice :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.jset ajoutez le contenu suivant :- Fichier :app .js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16const { 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
pgModule 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 lepostgresmot de passe de l'utilisateur de la base de données que vous avez défini dans la section précédente.Remarque Le
pgmodule 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
pgmodules :npm install pg -
Testez l'application :
node app.jsSi 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 7FROM 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.jspour permettre à l'application de se connecter à ladatabasehôte au lieu delocalhost:- Fichier :app /app.js
1 2 3 4 5 6 7const 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
docker0interface réseau. Utilisezifconfigouippour afficher cette interface :ifconfig docker0Le 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.confdans un éditeur de texte et ajoutez la ligne suivante :- Fichier :/ etc/postgresql/9.5/main/pg_hba.conf
1host 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_imageLe
--add-hostl'option définit unedatabasehost, qui pointe vers l'adresse IP de l'hôte Docker. Déclaration de ladatabasehé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
pingpour tester la connexion à ladatabasehé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 eth0Vous 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
postgresimage :docker pull postgres -
Assurez-vous que votre
backup.sqlle fichier est dans votre répertoire de travail actuel, puis exécutez lepostgresimage :docker run -d -v `pwd`:/backup/ --name pg_container postgresLe
-vL'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--linkoption pour connecter le conteneur à pg_container :docker run -d --name node_container --link=pg_container:database node_imageCela liera le
pg_containersous le nom d'hôtedatabase. -
Ouvrez
/etc/hostsdans node_container pour confirmer que le lien a bien été fait :docker exec -it node_container cat /etc/hostsIl devrait y avoir une ligne semblable à la suivante :
- Fichier :/ etc/hôtes
172.17.0.2 database pg_container
Cela montre que
pg_containera é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
databasehô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.ymlfichier 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 25version: '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_containeretnode_containerde 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. Leslinksl'entrée a la même fonction que le--linkoption dans leruncommande 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.jspour supprimer ces valeurs :- Fichier :app .js
1 2 3 4 5 6 7 8 9 10 11const 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.jsdepuis 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