Al usar Docker para contener sus aplicaciones, es una práctica común ejecutar cada componente de la aplicación en un contenedor separado. Por ejemplo, un sitio web puede tener un servidor web, una aplicación y una base de datos, cada uno ejecutándose en su propio contenedor.
Configurar los contenedores para que se comuniquen entre sí y con la máquina host puede ser un desafío. Esta guía usará una aplicación de ejemplo simple para demostrar los conceptos básicos de la comunicación del contenedor Docker. La aplicación consistirá en una aplicación Node.js que lee datos de una base de datos PostgreSQL.
Antes de comenzar
Instalar Docker CE
Necesitará un Linode con Docker CE instalado para seguir los pasos de esta guía.
Para instalar Docker CE (Community Edition), siga las instrucciones de una de las siguientes guías:
-
Instalación y uso de Docker en Ubuntu y Debian
-
Instalación y uso de Docker en CentOS y Fedora
Para obtener instrucciones completas sobre aún más distribuciones de Linux, consulte la sección Instalar el motor Docker de la documentación oficial de Docker.
Ejemplo de aplicación Node.js
La aplicación de ejemplo utilizada en esta guía será una aplicación simple de Node.js que leerá "Hola mundo" desde una base de datos de PostgreSQL y lo imprimirá en la consola. En esta sección, construirá y probará la aplicación en su Linode sin usar contenedores.
Instalar y configurar PostgreSQL
-
Actualice su sistema:
sudo apt update && sudo apt upgrade
-
Instalar PostGreSQL:
sudo apt install postgresql postgresql-contrib
-
Cambia el
postgres
contraseña del usuario:sudo passwd postgres
-
Establecer una contraseña para
postgres
usuario de la base de datos:su - postgres psql -d template1 -c "ALTER USER postgres WITH PASSWORD 'newpassword';"
-
Cree una base de datos para la aplicación de ejemplo y conéctese a ella:
createdb nodejs psql nodejs
-
Agregue "Hola mundo" a la base de datos:
nodejs=# CREATE TABLE hello (message varchar); nodejs=# INSERT INTO hello VALUES ('Hello world'); nodejs=# \q
-
Cree un volcado de la base de datos para su uso posterior:
pg_dumpall > backup.sql
-
Cerrar sesión como
postgres
Usuario de Linux:exit
-
Copie el volcado de datos a su directorio de inicio:
sudo cp /var/lib/postgresql/backup.sql ~/.
-
Dado que se conectará a esta base de datos desde un contenedor (que tendrá una dirección IP distinta de
locahost
), deberá editar el archivo de configuración de PostgreSQL para permitir conexiones desde direcciones remotas. Abra/etc/postgresql/9.5/main/postgresql.conf
en un editor de texto. Descomente laslisten_addresses
línea y configúrelo en '*':- Archivo:/ 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;
Habilite e inicie
postgresql
servicio:sudo systemctl enable postgresql sudo systemctl start postgresql
Crea una aplicación Hello World
-
Instalar Nodo y NPM:
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install nodejs
-
Navegue hasta el directorio de inicio y cree un directorio:
cd mkdir app && cd app
-
Usando un editor de texto, cree
app.js
y agregue el siguiente contenido:- Archivo:aplicación .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() })
Esta aplicación utiliza el
pg
Módulo NPM (node-postgres) para conectarse a la base de datos creada en el apartado anterior. Luego consulta la tabla 'hola' (que devuelve el mensaje "Hola mundo") y registra la respuesta en la consola. Reemplazar'newpassword'
conpostgres
contraseña de usuario de la base de datos que estableció en la sección anterior.Nota El
pg
El módulo también puede usar variables de entorno para configurar la conexión del cliente. Esta es la opción recomendada para aplicaciones de producción. Lea más sobre las variables de entorno en la documentación de node-postgres.Instale el
pg
módulo:npm install pg
Prueba la aplicación:
node app.js
Si la base de datos está configurada correctamente, se mostrará "Hola mundo" en la consola.
Conectar contenedor a Docker Host
Esta sección ilustra un caso de uso en el que la aplicación Node.js se ejecuta desde un contenedor de Docker y se conecta a una base de datos que se ejecuta en el host de Docker.
Configurar contenedor Docker
-
Regrese a su directorio de inicio:
cd
-
Cree un Dockerfile para ejecutar la aplicación Node.js:
- Archivo: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
La imagen creada a partir de este Dockerfile copiará la
app/
directorio a la nueva imagen. Editarapp.js
para permitir que la aplicación se conecte a ladatabase
host en lugar delocalhost
:- Archivo:aplicación /app.js
1 2 3 4 5 6 7
const client = new Client({ user: 'postgres', host: 'database', database: 'nodejs', password: 'newpassword', port: 5432 })
Cree una imagen desde Dockerfile:
docker build -t node_image .
Conectar contenedor a base de datos
-
Docker configura automáticamente una red puente predeterminada , al que se accede a través de
docker0
interfaz de red. Usaifconfig
oip
para ver esta interfaz:ifconfig docker0
El resultado será similar al siguiente:
La dirección IP interna del host Docker (su Linode) es 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)
-
Permita que PostgreSQL acepte conexiones desde la interfaz de Docker. Abra
/etc/postgresql/9.5/main/pg_hba.conf
en un editor de texto y agregue la siguiente línea:- Archivo:/ etc/postgresql/9.5/main/pg_hba.conf
1
host all postgres 172.17.0.0/16 password
Dado que 172.17.0.1 es la IP del host Docker, todos los contenedores en el host tendrán una dirección IP en el rango 172.17.0.0/16.
Reinicie la base de datos:
sudo systemctl restart postgresql
Inicie el contenedor:
docker run -d --add-host=database:172.17.0.1 --name node_container node_image
El
--add-host
opción define unadatabase
host, que apunta a la dirección IP del host Docker. Declarando ladatabase
host en tiempo de ejecución, en lugar de codificar la dirección IP en la aplicación, ayuda a mantener el contenedor reutilizable.Desde dentro del contenedor, use
ping
para probar la conexión a ladatabase
anfitrión:docker exec -it node_container ping database
A cada contenedor de Docker también se le asigna su propia dirección IP desde el bloque 172.17.0.0/16. Encuentre la dirección IP de este contenedor con
ip
:docker exec -it node_container ip addr show eth0
Puede probar esta conexión haciendo ping a esta dirección desde el host de Docker.
Ejecute la aplicación:
docker exec -it node_container node home/app.js
Si la configuración fue exitosa, el programa debería mostrar la salida de la consola "Hello world" como antes.
Conectar dos contenedores
En esta sección, tanto la aplicación como la base de datos se ejecutarán en contenedores separados. Puede usar la imagen oficial de postgres de Docker Hub y cargarla en el volcado de SQL creado anteriormente.
Precaución No debe almacenar datos de la base de datos de producción dentro de un contenedor Docker. Los contenedores deben tratarse como entidades efímeras:si un contenedor falla inesperadamente o se reinicia, se perderán todos los datos de la base de datos.
-
Detenga y elimine el contenedor Node.js:
docker stop node_container docker rm node_container
-
Tire del
postgres
imagen:docker pull postgres
-
Asegúrese de que su
backup.sql
el archivo está en su directorio de trabajo actual, luego ejecutepostgres
imagen:docker run -d -v `pwd`:/backup/ --name pg_container postgres
El
-v
La opción monta su directorio de trabajo actual en/backup/
directorio en el nuevo contenedor. -
El nuevo contenedor iniciará automáticamente la base de datos de postgres y creará el usuario de postgres. Ingrese al contenedor y cargue el volcado de SQL:
docker exec -it pg_container bash cd backup psql -U postgres -f backup.sql postgres exit
-
Vuelva a ejecutar la imagen del nodo. Esta vez, en lugar de
--add-host
, use el--link
opción para conectar el contenedor a pg_container:docker run -d --name node_container --link=pg_container:database node_image
Esto vinculará el
pg_container
bajo el nombre de hostdatabase
. -
Abra
/etc/hosts
en node_container para confirmar que se ha realizado el enlace:docker exec -it node_container cat /etc/hosts
Debería haber una línea similar a la siguiente:
- Archivo:/ etc./hosts
172.17.0.2 database pg_container
Esto muestra que
pg_container
se ha asignado a la dirección IP 172.17.0.2 y está vinculado a este contenedor a través del nombre de hostdatabase
, como se esperaba. -
Dado que la aplicación Node.js aún espera conectarse a una base de datos PostgreSQL en la
database
host, no es necesario realizar más cambios. Debería poder ejecutar la aplicación como antes:docker exec -it node_container node home/app.js
Usando Docker Compose
Usando el
--link
o--host
Las opciones cada vez que lanza sus contenedores pueden ser engorrosas. Si su servidor o cualquiera de los contenedores falla, deben volver a conectarse manualmente. Esta no es una situación ideal para cualquier aplicación que requiera disponibilidad constante. Afortunadamente, Docker proporciona Docker Compose para administrar múltiples contenedores y vincularlos automáticamente cuando se lanzan. Esta sección utilizará Docker Compose para reproducir los resultados de la sección anterior.Nota Para obtener una explicación más completa de Docker Compose y cómo escribir
docker-compose.yml
archivos de configuración, consulte nuestra guía completa de Docker Compose.-
Instalar 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
-
En el mismo directorio que su Dockerfile, cree un
docker-compose.yml
archivo con el siguiente contenido:- Archivo:docker -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: {}
Cuando ejecute Docker Compose con este archivo, creará el
pg_container
ynode_container
de la sección anterior. Como antes, el contenedor de la base de datos utilizará la imagen oficial de PostgreSQL, mientras que el contenedor de la aplicación se creará a partir de su Dockerfile. Loslinks
la entrada cumple la misma función que--link
opción enrun
comando usado anteriormente.Docker Compose también le permite configurar valores de entorno, por lo que puede simplificar la aplicación para usarlos en lugar de tener los valores codificados. Editar
app.js
para eliminar estos valores:- Archivo:aplicación .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() })
Eliminar los contenedores anteriores:
docker rm -f node_container pg_container
Use Docker Compose para mostrar los contenedores:
docker-compose up -d
Cargue los datos de ejemplo en el nuevo contenedor:
docker cp backup.sql pg_container:/ docker exec -it pg_container psql -U postgres -f backup.sql postgres
Ejecute
app.js
desde el contenedor de la aplicación:docker exec -it node_container node home/app.js
La aplicación debería funcionar como antes.
Conclusión
De forma predeterminada, Docker asigna automáticamente una dirección IP a cada contenedor y al host de Docker. Puede conectar manualmente servicios entre contenedores usando estas direcciones (suponiendo que su firewall permita la conexión).
Sin embargo, Docker también proporciona varios envoltorios convenientes alrededor de estas conexiones para ayudarlo a acelerar y simplificar el proceso de conexión. Puede conectar su host Docker a un contenedor con un nombre de host único o vincular directamente dos contenedores. El uso de Docker Compose puede simplificar este proceso aún más al permitirle declarar conexiones en
docker-compose.yml
para que se establezcan automáticamente cuando se muestren los contenedores.Hay otras opciones de conexión que no se trataron en esta guía. Por ejemplo, puede ejecutar un contenedor usando
--net="host"
, que compartirá la pila de red de ese contenedor con el host de Docker:localhost
en el contenedor apuntará alocalhost
en el host de Docker. También puede exponer puertos en cada contenedor de Docker o configurar la red de puente predeterminada para obtener más flexibilidad. Para obtener una discusión más detallada de estas opciones, consulte los enlaces en la sección Más información a continuación.Más información
Es posible que desee consultar los siguientes recursos para obtener información adicional sobre este tema. Si bien estos se proporcionan con la esperanza de que sean útiles, tenga en cuenta que no podemos garantizar la precisión o la puntualidad de los materiales alojados externamente.
- Docker:comprensión de la comunicación de contenedores
- Contenedores de enlace
- Conexiones de contenedores
Docker Cómo ejecutar contenedores Docker
Cómo eliminar contenedores Docker
Cómo detener los contenedores de Docker
Cómo nombrar o renombrar contenedores Docker
Cómo gestionar contenedores Docker
Cómo configurar espacios de nombres de red en contenedores Docker