Как создать БД для контейнера MongoDB при запуске?
Я работаю с Docker, и у меня есть стек с PHP, MySQL, Apache и Redis. Мне нужно добавить MongoDB сейчас, поэтому я проверил Dockerfile для последней версии, а также файл docker -entrypoint.sh из MongoDB Dockerhub, но я не смог найти способ настройки по умолчанию DB, admin/password и, возможно, auth-метод для контейнера из файла docker-compose.yml
.
В MySQL вы можете настроить некоторые переменные ENV, например:
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}
И это установит базу данных и пароль пользователя как пароль root
.
Есть ли способ достичь этого с MongoDB? У кого-нибудь есть опыт или обход?
Ответы
Ответ 1
Официальный образ mongo
объединил PR, чтобы включить функциональность для создания пользователей и баз данных при запуске.
Инициализация базы данных будет выполняться, когда в каталоге /data/db
ничего не заполнено.
Настройка администратора
Переменные среды для управления настройкой пользователя root
-
MONGO_INITDB_ROOT_USERNAME
-
MONGO_INITDB_ROOT_PASSWORD
пример
docker run -d \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongod
Вам не нужно/нельзя использовать --auth
в командной строке, так как сценарий docker entrypoint.sh добавляет это, когда существуют переменные среды.
Инициализация базы данных
В образе также /docker-entrypoint-initdb.d/
путь /docker-entrypoint-initdb.d/
для развертывания пользовательских сценариев установки .js
или .sh
которые будут запускаться один раз при инициализации базы данных. Скрипты .js
будут запускаться в test
по умолчанию или в MONGO_INITDB_DATABASE
если это определено в среде.
COPY mysetup.sh /docker-entrypoint-initdb.d/
или же
COPY mysetup.js /docker-entrypoint-initdb.d/
Простой файл инициализации javascript, который демонстрирует ведение журнала и способ выхода с ошибкой (для проверки результатов).
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)
}
Ответ 2
Вот еще одно более чистое решение с использованием docker-compose
и сценария js
.
В этом примере предполагается, что оба файла (docker-compose.yml и mongo-init.js) находятся в одной папке.
докер-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:ro
Mongo-init.js
db.createUser(
{
user: "<user for database which shall be created>",
pwd: "<password of user>",
roles: [
{
role: "readWrite",
db: "<database to create>"
}
]
}
);
Затем просто запустите службу, выполнив следующую команду docker-compose
docker-compose up --build -d mongodb
Ответ 3
Вот рабочее решение, которое создает admin-user
с паролем, дополнительной базой данных (test-db
) и test-user
в этой базе данных.
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',
},
],
});
Сложно было понять, что файлы *.js были запущены без проверки подлинности. Решение проверяет подлинность сценария как admin-user
- admin
базе данных admin
. MONGO_INITDB_DATABASE admin
имеет важное значение, в противном случае сценарий будет выполняться по сравнению с test
БД. Проверьте исходный код docker-entrypoint.sh.
Ответ 4
В случае, если кто-то ищет, как настроить MongoDB с помощью аутентификации с помощью docker-compose
, вот пример конфигурации с использованием переменных среды:
version: "3.3"
services:
db:
image: mongo
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=<YOUR_PASSWORD>
ports:
- "27017:27017"
При запуске docker-compose up
ваш экземпляр mongo запускается автоматически с включенным auth. У вас будет база данных администратора с заданным паролем.
Ответ 5
На изображение Mongo может повлиять переменная MONGO_INITDB_DATABASE
, но она не создаст базу данных. Эта переменная определяет текущую базу данных при выполнении скриптов /docker-entrypoint-initdb.d/*
. Поскольку вы не можете использовать переменные окружения в сценариях, выполняемых Mongo, я выбрал сценарий оболочки:
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
В качестве альтернативы, вы можете сохранить init-mongo.sh
в init-mongo.sh
(docker config create
) и смонтировать его:
configs:
init-mongo.sh:
external: true
...
services:
mongo:
...
configs:
- source: init-mongo.sh
target: /docker-entrypoint-initdb.d/init-mongo.sh
И секреты могут не храниться в файле.
Ответ 6
Если вы хотите удалить имена пользователей и пароли с вашего docker-compose.yml, вы можете использовать Docker Secrets, вот как я подошел к нему.
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
У меня есть опция file: для моих секретов, однако вы также можете использовать внешний: и использовать секреты в рое.
Секреты доступны для любого скрипта в контейнере в /var/run/secrets
В документации Docker говорится об хранении конфиденциальных данных...
https://docs.docker.com/engine/swarm/secrets/
Вы можете использовать секреты для управления любыми конфиденциальными данными, которые требуется контейнеру во время выполнения, но вы не хотите хранить их на изображении или в контроле источника, например:
Имена пользователей и пароли TLS-сертификаты и ключи SSH-ключи Другие важные данные, такие как имя базы данных или внутреннего сервера Общие строки или двоичный контент (до 500 кб)
Ответ 7
это работает правильно для меня, однако это не работает: docker run -d \ -e MONGO_INITDB_ROOT_USERNAME = admin \ -e MONGO_INITDB_ROOT_PASSWORD = пароль \ mongod