Je travaille avec Docker et j'ai une pile avec PHP, MySQL, Apache et Redis. Je dois maintenant ajouter MongoDB pour vérifier le fichier Dockerfile et la version la plus récente le fichier docker-entrypoint.sh du fichier MongoDB Dockerhub mais je ne pouvais pas trouver un moyen de configurer une base de données, un utilisateur/mot de passe administrateur par défaut et éventuellement une méthode auth pour le conteneur à partir d'un docker-compose.yml
fichier.
Dans MySQL, vous pouvez configurer certaines variables ENV, comme par exemple:
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}
Et cela configurera la base de données et le nom d'utilisateur/mot de passe en tant que mot de passe root
.
Existe-t-il un moyen d'obtenir le même résultat avec MongoDB? Quelqu'un a une expérience ou une solution de contournement?
Le officiel mongo
image a a fusionné un PR pour inclure la fonctionnalité afin de créer des utilisateurs et des bases de données au démarrage.
L’initialisation de la base de données s’exécutera s’il n’ya rien renseigné dans le fichier /data/db
répertoire.
Les variables d’environnement permettant de contrôler la configuration utilisateur "root" sont les suivantes:
MONGO_INITDB_ROOT_USERNAME
MONGO_INITDB_ROOT_PASSWORD
Exemple
docker run -d \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongod
Vous n'avez pas besoin/ne pouvez pas utiliser --auth
sur la ligne de commande, car le script docker entrypoint.sh l’ajoute lorsque les variables d’environnement existent.
L'image fournit également le /docker-entrypoint-initdb.d/
chemin d'accès au déploiement personnalisé .js
ou .sh
scripts de configuration à exécuter une fois lors de l’initialisation de la base de données. .js
Les scripts seront exécutés sur test
par défaut ou MONGO_INITDB_DATABASE
_ si défini dans l'environnement.
COPY mysetup.sh /docker-entrypoint-initdb.d/
ou
COPY mysetup.js /docker-entrypoint-initdb.d/
Un fichier javascript d'initialisation simple qui montre la journalisation et comment sortir avec une erreur (pour la vérification des résultats).
let error = true
let res = [
db.container.drop(),
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)
}
Voici une autre solution plus propre en utilisant docker-compose
et un script js
.
Cet exemple suppose que les deux fichiers (docker-compose.yml et mongo-init.js) se trouvent dans le même dossier.
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>"
}
]
}
);
Ensuite, démarrez simplement le service en exécutant la commande suivante docker-compose
docker-compose up --build -d mongodb
Voici une solution de travail qui crée admin-user
utilisateur avec mot de passe, base de données supplémentaire (test-db
), et test-user
dans cette base de données.
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: 'admin',
},
],
});
La partie délicate était de comprendre que les fichiers * .js étaient exécutés sans authentification. La solution authentifie le script en tant que admin-user
dans la base de données admin
. MONGO_INITDB_DATABASE admin
est essentiel, sinon le script serait exécuté sur la test
db. Vérifiez le code source de docker-entrypoint.sh .
Si quelqu'un cherche à savoir comment configurer MongoDB avec authentification à l'aide de docker-compose
, voici un exemple de configuration utilisant des variables d’environnement:
version: "3.3"
services:
db:
image: mongo
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=<YOUR_PASSWORD>
ports:
- "27017:27017"
Lorsque vous exécutez docker-compose up
_ votre instance Mongo est exécutée automatiquement avec l’autorisation activée. Vous aurez une base de données admin avec le mot de passe donné.
L'image Mongo peut être affectée par MONGO_INITDB_DATABASE
variable , mais la base de données ne sera pas créée. Cette variable détermine la base de données actuelle lors de l'exécution de /docker-entrypoint-initdb.d/*
scripts . Puisque vous ne pouvez pas utiliser les variables d'environnement dans les scripts exécutés par Mongo, je suis allé avec un script 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 = '$(cat "$MONGO_INITDB_ROOT_PASSWORD_FILE")';
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
Alternativement, vous pouvez stocker init-mongo.sh
dans les configurations (docker config create
) et montez-le avec:
configs:
init-mongo.sh:
external: true
...
services:
mongo:
...
configs:
- source: init-mongo.sh
target: /docker-entrypoint-initdb.d/init-mongo.sh
Et les secrets ne peuvent pas être stockés dans un fichier.
Si vous souhaitez supprimer les noms d'utilisateur et les mots de passe de votre fichier docker-compose.yml, vous pouvez utiliser Docker Secrets , voici comment je l'ai abordé.
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.txt
J'ai utilisé le fichier : pour mes secrets, mais vous pouvez aussi utiliser external: et utilise les secrets d'un essaim.
Les secrets sont disponibles pour n’importe quel script du conteneur dans/var/run/secrets
La documentation de Docker a ceci à dire sur le stockage de données sensibles ...
https://docs.docker.com/engine/swarm/secrets/
Vous pouvez utiliser des secrets pour gérer les données sensibles dont un conteneur a besoin au moment de l'exécution, mais vous ne souhaitez pas stocker dans l'image ou dans le contrôle de source, tels que:
Noms d'utilisateur et mots de passe Certificats et clés TLS Clés SSH Autres données importantes telles que le nom d'une base de données ou d'un serveur interne Chaînes génériques ou contenu binaire (taille maximale de 500 Ko)