Docker compose + mongo

Esto de levantar contenedores a golpe de línea de comandos está muy interesante... pero ¿No hay una forma más fácil de ejecutar todo ésto? Lo suyo sería poder crear un comando sencillo que permitiera a otros desarrolladores levantar o tirar ésto, sin conocer detalles.

Con docker compose podemos esconder toda esta configuración en un fichero yml.

Manos a la obra

  • Volvemos al inicio del casillero, si estás siguiendo el vídeo anterior, vamos a eliminar el contenedor de my-mongo-db:
docker rm -f my-mongo-db
  • Lo que vamos a hacer ahora es pasar toda la configuración de parámetros a un fichero, de esta manera tenemos algo más legible y mantenible y simplificamos su ejecución (evitamos errores típicos del tipo: me he equivocado al copiar y pegar, he bailado parámetros, ha cambiado la configuración), nombramos el fichero ./docker-compose.yml y el contenido que tendríamos sería

./docker-compose.yml

version: "3.8"
services:
  my-mongo-db:
    container_name: my-mongo-db
    image: mongo:4.4.3
    ports:
      - "27017:27017"
    volumes:
      - misdatosmongo:/data/db
volumes:
  misdatosmongo:

En la carpeta de trabajo comprobamos que tenemos este fichero:

ls
cat docker-compose.yml

sí estamos Windows habríamos usaríamos los comandos dir y type docker-compose.yml

¿Qué estamos haciendo aquí?

  • Primero indicamos que el fichero yml cumple con las especificaciones de la versión 3.8, si en un futuro queremos subir a una versión nueva, miraríamos los breaking changes y migraríamos las entradas del fichero que hicieran falta, fijando versión nos ahorramos disgustos inesperados actualizando Docker.
version: "3.8"

Después le decimos que contenedores vamos a levantar, en este caso sólo uno:

my-mongo-db:
  container_name: my-mongo-db
  image: mongo:4.4.3
  ports:
    - "27017:27017"
  volumes:
    - misdatosmongo:/data/db

Le indicamos que imagen, puertos y volúmenes va a usar ese contenedor.

Y para finalizar le indicamos que volúmenes vamos a usar en este docker compose (si nos olvidamos de añadir esta entrada nos dará un error al levantar el contenedor diciendo que misdatosmongo no está definido en el fichero docker-compose):

volumes:
  misdatosmongo:

Para aprender más sobre este tipo de ficheros de configuración puedes ver este enlace.

  • Vamos a ejecutar el siguiente comando para levantarlo:
docker compose up
  • Dejamos ese terminal funcionando, y desde otro terminal podemos entrar en modo interactivo.
docker exec -it my-mongo-db sh

Y comprobar que tenemos todo funcionando:

mongo
show dbs

Nos salimos del mismo.

Primero de mongo

exit

Después del terminal abierto en el contenedor

exit
  • Podemos parar el contenedor volviendo al terminal en el que lo levantamos y presionando la combinación de teclas CTRL+C.

  • Cuando nos hartemos, podemos tirar abajo ésto con el siguiente comando:

docker compose down

En algunos post verás que invocan docker-compose con un guión, esto es para versiones antiguas de Docker las últimas ya tienen incorporado docker compose en el cli, aunque en tech preview, más info Compose CLI Tech Preview y que no está implementado todavía

Si estás trabajando, por ejemplo con nodejs, es muy común añadir estos comandos en la sección de scripts de tu package.json

¿Qué pasa con el backup de la base de datos? con esta configuración tendríamos que seguir creándolo por nuestra cuenta.

Si queremos, podríamos añadir unos pasos en nuestro proyecto para automarizar ese proceso. Os dejamos un código escrito en nodejs:

import { promisify } from "util";
import childProcess from "child_process";
const runCommand = async (command) => {
  console.log(command);
  const { stdout, stderr } = await promisify(childProcess.exec)(command);
  console.log(stdout);
  console.error(stderr);
};

export const restoreMongoDBBackup = async () => {
  const copySeedDataCommand = "docker cp backup my-mongo-db:/opt/app";
  const restoreBackupCommand = `docker exec my-mongo-db mongorestore --db mymovies /opt/app`;

  await runCommand(copySeedDataCommand);
  await runCommand(restoreBackupCommand);
};

Como vemos, solamente tendríamos que ejecutar el método restoreMongoDBBackup para lanzar los mismos comandos que en el vídeo anterior, con la salvedad de que el comando mongorestore lo ejecutamos directamente con el comando docker exec sin necesidad de estar en modo interactivo.

¿Te gusta el mundo Devops?

En Lemoncode impartimos un Bootcamp Devops Online, en él encontrarás todos los recursos necesarios: clases de los mejores profesionales del sector, tutorías en cuanto las necesites y ejercicios para desarrollar lo aprendido en los distintos módulos. Si quieres saber más puedes pinchar aquí para más información sobre este Bootcamp Devops.