Подтвердить что ты не робот

Как создать БД для контейнера 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? У кого-нибудь есть опыт или обход?

4b9b3361

Ответ 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