Ejecutar PostgreSQL usando Docker Compose

Ejecutar PostgreSQL usando Docker Compose
Docker-composa se puede usar para automatizar fácilmente las implementaciones de contenedores múltiples. Una de las tareas más desafiantes mientras se ejecuta tales implementaciones es separar los datos del software.

Mientras que los contenedores son efímeros, los datos del usuario deben persistir. Un ejemplo clásico, de esto es cuando intentamos ejecutar imágenes de contenedores de bases de datos. Si destruye el contenedor de la base de datos, los datos también se pierden. Lo que queremos es una situación en la que la imagen del contenedor de, por ejemplo, PostgreSQL versión 9, se puede reemplazar con una imagen de la versión 10 sin que tengamos que perder datos. Esta es la forma de Docker de actualizar el software, no cae dentro del contenedor y actualiza los paquetes usando un Administrador de paquetes. Reemplaza toda la imagen del contenedor.

Veamos algunas dificultades que puede encontrar mientras hace esto y cómo podemos hacer que el proceso sea mucho más suave y limpio desde un punto de vista operativo.

Requisitos previos

  1. Una instalación de Docker
  2. Comprensión básica de Docker CLI y Docker-Compose

Docker volúmenes y comportamiento predeterminado de PostgreSQL

Los volúmenes de Docker son la forma recomendada de persistir los datos. Estos son sistemas de archivos administrados por Docker Daemon y la mayoría de las veces se espera que cree uno y lo monte dentro de su contenedor cuando lo inicie. La imagen oficial de Postgres, sin embargo, viene con un volumen predefinido en su descripción de la imagen.

Esto significa que cuando ejecuta una imagen PostgreSQL como contenedor, crea un volumen para sí mismo y almacena datos allí.

$ Docker Run -d - -Name MyDB Postgres

Puede enumerar los volúmenes existentes usando el comando Docker Volume LS y puede inspeccionar el contenedor Docker MyDB para ver cuáles de estos volúmenes se monta dentro del contenedor de la base de datos.

$ Docker Volumen LS
Nombre del volumen del conductor
Local 8328940661C0703ED867B004EA6343B9432E70069280B71CFCE592ECDD12E55D
$ Docker Inspect MyDB

"Montes": [

"Tipo": "Volumen",
"Nombre": "8328940661c0703ed867b004ea6343b9432e70069280b71cfce592ecdd12e55d",
"Fuente": "/var/lib/docker/volumes/8328940661C0703ED867B004EA6343B9432E70069280B71CF
CE592ECDD12E55D/_DATA ",
"Destino": "/var/lib/postgresql/data",
"Conductor": "local",
"Modo": "",
"RW": verdadero,
"Propagación": ""

],

Notarás que el volumen tiene un nombre bastante hostil y está montado en /var/lib/postgresql/data.

Eliminemos este contenedor y el volumen asociado por ahora:

$ docker rm -f mydb
$ Docker Volumen RM 8328940661C0703ED867B004EA6343B9432E70069280B71CFCE592ECDD12E55D

Lo mismo es cierto cuando crea un contenedor utilizando un archivo simple de Docker-Compose. Lo siguiente es un Docker-Compose.Archivo YML colocado dentro de un directorio llamado Postgres.

Versión: '3'
servicios:
MyDB:
Imagen: Postgres

Puede alimentarlo a Docker-Compose, abriendo un terminal en el mismo directorio donde este archivo está y en ejecución:

$ Docker -Compose Up -d

Esto crea un contenedor y un volumen muy parecido al comando Docker Run que vimos anteriormente. Sin embargo, ambos métodos, uno que involucra Docker-Compose y otro Docker CLI tiene un problema fatal y eso está en juego cuando necesita reemplazar la vieja imagen de Postgres por una nueva.

Nuevos volúmenes cada vez

Si elimina la implementación anterior ejecutando:

$ Docker-Compose Down

El contenedor y la red se eliminan, pero el volumen se adhiere y sus datos son seguros dentro de él. Sin embargo, la próxima vez que corras:

$ Docker -Compose Up -d

Componer creará un nuevo volumen y montaje que en lugar de usar el volumen creado anteriormente. ¿Y cómo puede recordar que el volumen anterior estaba destinado a este contenedor postgresql particular de todos modos?? Pero el pobre usuario que quizás no sepa el concepto de volúmenes se confundirá preguntándose dónde se han ido todos los datos.

Volumen definido por el usuario

Para eludir este problema, podemos usar la información que recopilamos anteriormente que nos mostró que el volumen está montado en /var/lib/postgresql/data. Dentro del contenedor, este directorio es donde Postgres almacena todas las tablas y bases de datos relevantes.

Ahora tenemos que definir un volumen dentro del archivo de composición y montarlo en este punto de montaje. Así es como el Docker-Compose.YML se vería como.

Versión: '3'
servicios:
MyDB:
Imagen: Postgres
Volúmenes:
- db-data:/var/lib/postgresql/data
Puertos:
- 5432: 5432
Volúmenes:
DB-Data:
Conductor: local

La última línea "Driver: Local" es completamente opcional y se menciona aquí solo para mostrar que el "Llave de nivel superior volúmenes " puede tener múltiples volúmenes definidos debajo de él. DB-Data es uno de esos volumen que a su vez tiene detalles, como los controladores, incluido como un bloque sangrado debajo de él.

Bajo el servicio MyDB tenemos la tecla Volúmenes una vez más. Este "nivel de servicio Clave de volúmenes " Es solo una lista de volúmenes definidos debajo de la tecla de volúmenes de nivel superior que se mapea en los puntos de montaje dentro de los contenedores

Cuando ejecuta el comando Docker-composte up -d la primera vez con la definición YML anterior, creará un volumen, no con una cadena aleatoria como su nombre, sino DB-bata como nombre. Luego, cada vez que derribe la aplicación (Docker-Compose hacia abajo) y luego volver a ejecutar la composición de Docker-Compose up -d intentará crear un volumen llamado DB-data, pero luego notaría que un volumen con ese nombre ya existe. Entonces volverá a montar útilmente el mismo volumen nuevamente. Bajemos la aplicación por ahora:

$ Docker-Compose Down

Usando PostgreSQL

La imagen oficial de Postgres expone el puerto 5432 para nuestra ventaja. Estrictamente hablando, esto no es necesario. Las bases de datos son solo uno de los muchos servicios que se ejecutan en una red Docker. Los otros servicios, como el servidor web, pueden hablar con la base de datos sin que se publique ningún puerto explícito. Esto se debe a que las redes de puente definidas por el usuario, como las que componen Docker crea para que sus aplicaciones se ejecuten, permitan que los contenedores de miembros se hablen libremente entre sí. Entonces, si el servidor web y la base de datos están en la misma red de puentes, pueden hablar entre sí incluso sin que se abran explícitamente los puertos.

Las bases de datos a menudo no están expuestas al mundo exterior, sino que acceden a otros servicios. Por lo tanto, publicar el puerto de Postgres no es algo que a menudo vería en la producción.

Sin embargo, experimentaremos con la aplicación en contenedores para ver si los datos realmente persisten para que podamos exponer y publicar los puertos por ahora. Modificar el Docker-Compose.archivo YML con opción de puertos adicionales.

Versión: '3'
servicios:
MyDB:
Imagen: Postgres
Volúmenes:
- db-data:/var/lib/postgresql/data
Puertos:
- 5432: 5432/TC
Volúmenes:
DB-Data:
Conductor: local

Ahora, estamos listos para interactuar con la instancia de Postgres utilizando el programa de cliente PGADmin. Puede instalar este cliente en su máquina local utilizando su método preferido si sigue este enlace. Después de instalar el cliente, puede conectarse al servidor de la base de datos, pero primero iniciemos el servidor de la base de datos.

$ Docker -Compose Up -d

Esta vez, las solicitudes entrantes en el puerto host de Docker 5432 se reenviarán al puerto 5432 del contenedor de la base de datos, donde el servidor Postgres puede procesarlo.

Conectando al servidor

Inicie el cliente pgadmin y puede acceder a él a través de su navegador web. En el tablero encontrarás la opción llamada Agregar nuevo servidor.

Dale un nombre razonable, vamos con "Mi base de datos ":

Y en la pestaña Conexiones ingrese la dirección donde se ejecuta la base de datos:

La dirección puede ser localhost si está ejecutando tanto Pgadmin y el contenedor Postgres se está ejecutando en la misma máquina. Si está ejecutando un contenedor Postgres en un VPS remoto, por ejemplo, entonces se necesitará la dirección IP de ese VPS aquí. En general, lo llamamos la dirección del host de Docker porque ahí es donde se está ejecutando Docker.

Dejaremos el campo de contraseña vacío y el número de puerto predeterminado 5432 también está bien. Guarde la configuración del servidor y creemos una base de datos allí.

Tras una conexión exitosa, puede ver todas las actividades internas:

En el menú del navegador podemos seleccionar rápidamente Mi base de datos servidor y en él haga clic con el botón derecho en la base de datos y crear una base de datos.

Creemos rápidamente una base de datos llamada Base de datos de muestra.

No tienes que crear nada más aquí. Ahora podemos cerrar la ventana y volver al terminal abierto en el mismo directorio donde nuestro Docker-Compose.YML vive.

$ Docker-Compose Down
$ Docker -Compose Up -d

El antiguo contenedor ya se ha ido y uno nuevo ha tomado su lugar. Puede abrir Pgadmin nuevamente y tendrá que volver a conectarse a esta base de datos (una contraseña vacía sería) y dentro de ella encontrará que todo es como lo ha dejado que sea. Incluso hay un Base de datos de muestra ahí.

Conclusión

Queríamos escribir un archivo Docker-Compose que hiciera actualizar Postgres. Si se produce una nueva imagen de Postgres Running Postgres 11, ahora puede extraer con confianza la nueva imagen y ejecutar una actualización sin preocuparse por el estado de la aplicación que se está perdiendo.

El comportamiento predeterminado de la imagen Postgres que es crear un nuevo volumen cada vez que se crea un contenedor no es una mala opción de diseño. Se implementa con los mejores intereses en el corazón.

Pero simplemente pospone a un nuevo usuario que se rascaría la cabeza preguntándose dónde se están perdiendo todos los datos y por qué hay tantos volúmenes en su anfitrión de Docker. Con suerte, eso ya no será un problema para los lectores.