Estoy trabajando con Docker y tengo una pila con PHP, MySQL, Apache y Redis. Necesito agregar MongoDB ahora, así que estaba verificando el Dockerfile para la última versión y también el archivo docker-entrypoint.sh del MongoDB Dockerhub, pero no pude encontrar una manera de configurar una base de datos predeterminada, usuario / contraseña de administrador y posiblemente autenticación método para el contenedor desde un docker-compose.ymlarchivo.
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 rootcontraseña.
¿Hay alguna forma de lograr lo mismo con MongoDB? ¿Alguien tiene alguna experiencia o solución?
                    
                        mongodb
                                docker
                                docker-compose
                                
                    
                    
                        ReynierPM
fuente
                
                fuente

Respuestas:
La imagen oficial se
mongoha fusionado con un PR para incluir la funcionalidad para crear usuarios y bases de datos al inicio.La inicialización de la base de datos se ejecutará cuando no haya nada en el
/data/dbdirectorio.Configuración de usuario administrador
Las variables de entorno para controlar la configuración del usuario "root" son
MONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORDEjemplo
No necesita / no puede usar
--authen la línea de comando ya que el script docker entrypoint.sh agrega esto cuando existen las variables de entorno.Inicialización de la base de datos
La imagen también proporciona la
/docker-entrypoint-initdb.d/ruta para implementar scripts de configuración.jso personalizados.shque se ejecutarán una vez en la inicialización de la base de datos..jsLos scripts se ejecutarántestde forma predeterminada oMONGO_INITDB_DATABASEsi están definidos en el entorno.o
Un archivo javascript simple de inicialización mongo shell que demuestra cómo configurar la
containercolección 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' }), db.other. ] printjson(res) if (error) { print('Error, exiting') quit(1) }fuente
set -eestá diciendoentrypoint.shque lea las variables de laENVdefinición para poder usar el mismo enfoque que el ejemplo de MySQL, ¿verdad? Como complemento a su respuesta me encontré con este PR donde al parecer alguien está trabajando en algo similar a la propuesta que acaba de venir desde otro punto de vistaset -ehace que todo el script se cierre cuando falla un comando, por lo que el script no puede fallar silenciosamente y arrancar mongo.&&todas partes.docker-entrypoint-initdb.ddirectorio lo hace extensible. Espero que se fusionenAquí otra solución más limpia usando
docker-composeunjsscript.Este ejemplo asume que ambos archivos (docker-compose.yml y mongo-init.js) se encuentran en la misma carpeta.
docker-compose.yml
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:romongo-init.js
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
Nota : El código de la carpeta docker-entrypoint-init.d solo se ejecuta si la base de datos nunca se ha inicializado antes.
fuente
volumesentrada./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:rovincula el archivo local./mongo-init.jsa la ruta del contenedor/docker-entrypoint-initdb.d/mongo-init.jscomo de solo lecturaro. Puede encontrar más detalles sobre cómo usar los volúmenes aquí: docs.docker.com/storage/volumesvolumesopción y agregue la ruta absoluta almongo-init.jsarchivo, por ejemploc:\docker\mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro.Aquí hay una solución funcional que crea un
admin-userusuario con una contraseña, una base de datos adicional (test-database) ytest-useren esa base de datos.Dockerfile:
FROM mongo:4.0.3 ENV MONGO_INITDB_ROOT_USERNAME admin-user ENV MONGO_INITDB_ROOT_PASSWORD admin-password ENV MONGO_INITDB_DATABASE admin ADD mongo-init.js /docker-entrypoint-initdb.d/mongo-init.js:
db.auth('admin-user', 'admin-password') db = db.getSiblingDB('test-database') db.createUser({ user: 'test-user', pwd: 'test-password', roles: [ { role: 'root', db: 'test-database', }, ], });La parte complicada fue entender que los archivos * .js se ejecutaron sin autenticar. La solución autentica el script como
admin-useren laadminbase de datos.MONGO_INITDB_DATABASE admines esencial, de lo contrario, el script se ejecutaría contra la base de datostest. Verifique el código fuente de docker-entrypoint.sh .fuente
La imagen de Mongo puede verse afectada por una
MONGO_INITDB_DATABASEvariable , pero no creará la base de datos. Esta variable determina la base de datos actual al ejecutar/docker-entrypoint-initdb.d/*scripts . Como no puede usar variables de entorno en scripts ejecutados por Mongo, elegí 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-passwdinit-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"]}); EOFAlternativamente, puede almacenar
init-mongo.shen configs (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 ideas al respecto.
fuente
$(cat "$MONGO_INITDB_ROOT_PASSWORD_FILE")Debería reemplazarse por$MONGO_INITDB_ROOT_PASSWORDestos días porque la imagen de Mongo ya maneja el secreto por nosotros. hub.docker.com/_/mongoEn caso de que alguien esté buscando cómo configurar MongoDB con autenticación usando
docker-compose, aquí hay una configuración de muestra usando variables de entorno:version: "3.3" services: db: image: mongo environment: - MONGO_INITDB_ROOT_USERNAME=admin - MONGO_INITDB_ROOT_PASSWORD=<YOUR_PASSWORD> ports: - "27017:27017"Cuando se ejecuta,
docker-compose upsu instancia de mongo se ejecuta automáticamente con la autenticación habilitada. Tendrá una base de datos de administrador con la contraseña proporcionada.fuente
mongo --username admin --password password --host localhost --port 27017No puedo conectarme porque los registros muestran a los usuarios y la base de datos se ha creado correctamente. ERROR:$ mongo --username admin --password password --host localhost --port 27017 MongoDB shell version v3.4.10 connecting to: mongodb://localhost:27017/ MongoDB server version: 3.6.5 WARNING: shell and server versions do not match 2018-06-07T13:05:09.022+0000 E QUERY [thread1] Error: Authentication failed. : DB.prototype._authOrThrow@src/mongo/shell/db.js:1461:20 @(auth):6:1 @(auth):1:2 exception: login failedmongo admin --username ADMIN --password PASSWORTconectarte a tu instancia de mongo.mongodb://root:example@localhost/my-db?authSource=adminSi está buscando eliminar nombres de usuario y contraseñas de su docker-compose.yml, puede usar Docker Secrets , así es como lo he abordado.
version: '3.6' services: db: image: mongo:3 container_name: mycontainer secrets: - MONGO_INITDB_ROOT_USERNAME - MONGO_INITDB_ROOT_PASSWORD environment: - MONGO_INITDB_ROOT_USERNAME_FILE=/var/run/secrets/MONGO_INITDB_ROOT_USERNAME - MONGO_INITDB_ROOT_PASSWORD_FILE=/var/run/secrets/MONGO_INITDB_ROOT_PASSWORD secrets: MONGO_INITDB_ROOT_USERNAME: file: secrets/${NODE_ENV}_mongo_root_username.txt MONGO_INITDB_ROOT_PASSWORD: file: secrets/${NODE_ENV}_mongo_root_password.txtHe usado la opción file: para mis secretos, sin embargo, también puedes usar external: y usar los secretos en un enjambre.
Los secretos están disponibles para cualquier script en el contenedor en / var / run / secrets
La documentación de Docker tiene esto que decir sobre el almacenamiento de datos confidenciales ...
https://docs.docker.com/engine/swarm/secrets/
Puede usar secretos para administrar los datos confidenciales que necesita un contenedor en tiempo de ejecución, pero no desea almacenarlos en la imagen o en el control de fuente, como:
Nombres de usuario y contraseñas Certificados y claves TLS Claves SSH Otros datos importantes como el nombre de una base de datos o un servidor interno Cadenas genéricas o contenido binario (hasta 500 kb de tamaño)
fuente
Dado este
.envarchivo:Y este
mongo-init.sharchivo:mongo --eval "db.auth('$MONGO_INITDB_ROOT_USERNAME', '$MONGO_INITDB_ROOT_PASSWORD'); db = db.getSiblingDB('$DB_NAME'); db.createUser({ user: '$DB_USER', pwd: '$DB_PASSWORD', roles: [{ role: 'readWrite', db: '$DB_NAME' }] });"Esto
docker-compose.ymlcreará la base de datos de administrador y el usuario de administrador, se autenticará como el usuario de administrador, luego creará la base de datos real y agregará el usuario real:version: '3' services: # app: # build: . # env_file: .env # environment: # DB_HOST: 'mongodb://mongodb' mongodb: image: mongo:4 environment: MONGO_INITDB_ROOT_USERNAME: admin-user MONGO_INITDB_ROOT_PASSWORD: admin-password DB_NAME: $DB_NAME DB_USER: $DB_USER DB_PASSWORD: $DB_PASSWORD ports: - 27017:27017 volumes: - db-data:/data/db - ./mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh volumes: db-data:fuente