Estoy trabajando con Docker y tengo una pila con PHP, MySQL, Apache y Redis. Necesito agregar MongoDB ahora, así que estaba revisando Dockerfile para obtener la última versión y también el archivo docker-entrypoint.sh de MongoDB Dockerhub , pero no pude encontrar una manera de configurar una base de datos predeterminada, un usuario administrador/contraseña y posiblemente auth. para el contenedor desde un archivo docker-compose.yml .
En MySQL puede configurar algunas variables ENV como por ejemplo:
db: image: mysql:5.7 env_file: .env environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} Y esto configurará la base de datos y el usuario/contraseña como la contraseña de root .
¿Hay alguna forma de lograr lo mismo con MongoDB? ¿Alguien tiene alguna experiencia o alguna solución?
Aquí otra solución más limpia usando docker-compose y un script js .
Este ejemplo asume que ambos archivos (docker-compose.yml y mongo-init.js) se encuentran en la misma carpeta.
version: '3.7' services: mongodb: image: mongo:latest container_name: mongodb restart: always environment: MONGO_INITDB_ROOT_USERNAME: <admin-user> MONGO_INITDB_ROOT_PASSWORD: <admin-password> MONGO_INITDB_DATABASE: <database to create> ports: - 27017:27017 volumes: - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro db.createUser( { user: "<user for database which shall be created>", pwd: "<password of user>", roles: [ { role: "readWrite", db: "<database to create>" } ] } );Luego simplemente inicie el servicio ejecutando el siguiente comando docker-compose
docker-compose up --build -d mongodbNota : el código en la carpeta docker-entrypoint-init.d solo se ejecuta si la base de datos nunca se ha inicializado antes.
La imagen de docker hub mongo ejecutará cualquier script en /docker-entrypoint-initdb.d/ cuando no haya nada en el directorio /data/db .
La imagen del contenedor mongo proporciona la ruta /docker-entrypoint-initdb.d/ para implementar secuencias de comandos de configuración .js o .sh personalizadas que se ejecutarán una vez en la inicialización de la base de datos. Los scripts .js se ejecutarán en test de forma predeterminada o MONGO_INITDB_DATABASE si está definido en el entorno.
COPY mysetup.sh /docker-entrypoint-initdb.d/o
COPY mysetup.js /docker-entrypoint-initdb.d/ Un archivo javascript de mongo shell de inicialización simple que demuestra cómo configurar la colección de container con datos, registro y cómo salir con un error (para la verificación de resultados).
let error = true let res = [ db.container.drop(), db.container.createIndex({ myfield: 1 }, { unique: true }), db.container.createIndex({ thatfield: 1 }), db.container.createIndex({ thatfield: 1 }), db.container.insert({ myfield: 'hello', thatfield: 'testing' }), db.container.insert({ myfield: 'hello2', thatfield: 'testing' }), db.container.insert({ myfield: 'hello3', thatfield: 'testing' }), db.container.insert({ myfield: 'hello3', thatfield: 'testing' }) ] printjson(res) if (error) { print('Error, exiting') quit(1) }Las variables de entorno para controlar la configuración del usuario "raíz" son
MONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORDEjemplo
docker run -d \ -e MONGO_INITDB_ROOT_USERNAME=admin \ -e MONGO_INITDB_ROOT_PASSWORD=password \ mongod o Dockerfile
FROM docker.io/mongo ENV MONGO_INITDB_ROOT_USERNAME admin ENV MONGO_INITDB_ROOT_PASSWORD password No necesita usar --auth en la línea de comando ya que el script docker entrypoint.sh agrega esto cuando detecta que existen variables de entorno.
UPD Hoy evito Docker Swarm, secretos y configuraciones. Lo ejecutaría con docker-compose y el archivo .env . Siempre y cuando no necesite escalado automático. Si lo hago, probablemente elegiría k8s. Y las contraseñas de la base de datos, cuenta raíz o no... ¿Realmente importan cuando ejecuta una única base de datos en un contenedor que no está conectado al mundo exterior? Me gustaría saber qué piensa al respecto, pero Stack Overflow probablemente no sea adecuado para este tipo de comunicación.
La imagen de Mongo puede verse afectada por la variable MONGO_INITDB_DATABASE , pero no creará la base de datos. Esta variable determina la base de datos actual cuando se ejecutan /docker-entrypoint-initdb.d/* scripts . Como no puede usar variables de entorno en scripts ejecutados por Mongo, opté por un script de shell:
docker-swarm.yml :
version: '3.1' secrets: mongo-root-passwd: file: mongo-root-passwd mongo-user-passwd: file: mongo-user-passwd services: mongo: image: mongo:3.2 environment: MONGO_INITDB_ROOT_USERNAME: $MONGO_ROOT_USER MONGO_INITDB_ROOT_PASSWORD_FILE: /run/secrets/mongo-root-passwd MONGO_INITDB_USERNAME: $MONGO_USER MONGO_INITDB_PASSWORD_FILE: /run/secrets/mongo-user-passwd MONGO_INITDB_DATABASE: $MONGO_DB volumes: - ./init-mongo.sh:/docker-entrypoint-initdb.d/init-mongo.sh secrets: - mongo-root-passwd - mongo-user-passwd init-mongo.sh :
mongo -- "$MONGO_INITDB_DATABASE" <<EOF var rootUser = '$MONGO_INITDB_ROOT_USERNAME'; var rootPassword = '$MONGO_INITDB_ROOT_PASSWORD'; var admin = db.getSiblingDB('admin'); admin.auth(rootUser, rootPassword); var user = '$MONGO_INITDB_USERNAME'; var passwd = '$(cat "$MONGO_INITDB_PASSWORD_FILE")'; db.createUser({user: user, pwd: passwd, roles: ["readWrite"]}); EOF Alternativamente, puede almacenar init-mongo.sh en configuraciones ( docker config create ) y montarlo con:
configs: init-mongo.sh: external: true ... services: mongo: ... configs: - source: init-mongo.sh target: /docker-entrypoint-initdb.d/init-mongo.shY los secretos no se pueden almacenar en un archivo.
Un par de puntos esenciales sobre el asunto.