[mongodb] 시작할 때 MongoDB 컨테이너 용 DB를 생성하는 방법은 무엇입니까?

저는 Docker로 작업하고 있으며 PHP, MySQL, Apache 및 Redis로 스택을 보유하고 있습니다. 지금 MongoDB를 추가해야하므로 Dockerfile 에서 최신 버전을 확인하고 MongoDB Dockerhub 에서 docker-entrypoint.sh 파일을 확인 했지만 기본 DB, 관리자 / 암호 및 인증을 설정하는 방법을 찾을 수 없었습니다. 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}

그러면 DB와 사용자 / 비밀번호를 비밀번호로 설정 root합니다.

MongoDB로 동일한 결과를 얻을 수있는 방법이 있습니까? 누구나 경험이나 해결 방법이 있습니까?



답변

공식 mongo이미지가 있다 기능을 포함하는 PR 병합 시작시 사용자와 데이터베이스를 만들 수 있습니다.

데이터베이스 초기화는 /data/db디렉토리에 아무것도 채워지지 않을 때 실행됩니다 .

관리자 사용자 설정

“루트”사용자 설정을 제어하는 ​​환경 변수는 다음과 같습니다.

  • MONGO_INITDB_ROOT_USERNAME
  • MONGO_INITDB_ROOT_PASSWORD

docker run -d \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=password \
  mongod

--authdocker entrypoint.sh 스크립트는 환경 변수가 존재할 때 이것을 추가하므로 명령 줄에서 사용할 필요가 없거나 사용할 수 없습니다 .

데이터베이스 초기화

이 이미지는 데이터베이스 초기화시 한 번 실행되는 /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/

데이터, 로깅 및 오류로 종료하는 방법 (결과 확인을 위해)을 사용 하여 콜렉션을 설정하는 방법을 보여주는 간단한 초기화 mongo 셸 자바 스크립트 파일입니다 container.

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)
}


답변

여기 docker-composejs스크립트 를 사용하여 또 다른 깨끗한 솔루션 입니다.

이 예에서는 두 파일 (docker-compose.yml 및 mongo-init.js)이 동일한 폴더에 있다고 가정합니다.

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: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

참고 : docker-entrypoint-init.d 폴더의 코드는 데이터베이스가 이전에 초기화 된 적이없는 경우에만 실행됩니다.


답변

다음 admin-user은 암호, 추가 데이터베이스 ( test-database) 및 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: 'test-database',
    },
  ],
});

까다로운 부분은 * .js 파일이 인증되지 않은 상태로 실행된다는 것을 이해하는 것이 었습니다. 솔루션은 스크립트를 데이터베이스 admin-user에있는 것처럼 인증 admin합니다. MONGO_INITDB_DATABASE admin그렇지 않으면 스크립트가 testdb 에 대해 실행 됩니다. docker-entrypoint.sh 의 소스 코드를 확인하십시오 .


답변

UPD 오늘의 피할 도커 떼, 비밀, 그리고 CONFIGS. 나는 그것을 실행하는 것 docker-compose.env파일. 자동 확장이 필요하지 않는 한. 그렇다면 아마도 k8s를 선택할 것입니다. 그리고 데이터베이스 암호, 루트 계정 여부 … 외부 세계와 연결되지 않은 컨테이너에서 단일 데이터베이스를 실행할 때 정말 중요합니까? .. 당신이 그것에 대해 어떻게 생각하는지 알고 싶지만 스택 오버플로 이런 종류의 의사 소통에 적합하지 않을 것입니다.

Mongo 이미지는 MONGO_INITDB_DATABASE 변수의 영향을받을 수 있지만 데이터베이스를 만들지는 않습니다. 이 변수는 /docker-entrypoint-initdb.d/* 스크립트를 실행할 때 현재 데이터베이스를 결정합니다 . 당신이 있기 때문에 할 수없는 몽고에 의해 실행 스크립트에서 환경 변수를 사용하여, 나는 쉘 스크립트로했다 :

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

또는 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

그리고 비밀은 파일에 저장할 수 없습니다.

문제에 대한 가지 요점 .


답변

누군가를 사용하여 인증으로 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당신의 몽고 인스턴스를 인증 활성화 자동으로 실행됩니다. 주어진 암호로 관리 데이터베이스를 갖게됩니다.


답변

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 : 옵션을 사용 했지만 external : 을 사용할 수도 있고 떼에서 비밀을 사용할 수도 있습니다 .

비밀은 / var / run / secrets에있는 컨테이너의 모든 스크립트에서 사용할 수 있습니다.

Docker 문서에는 민감한 데이터 저장에 대해 언급되어 있습니다.

https://docs.docker.com/engine/swarm/secrets/

비밀을 사용하여 컨테이너가 런타임에 필요하지만 이미지 또는 소스 제어에 저장하지 않으려는 민감한 데이터를 관리 할 수 ​​있습니다.

사용자 이름 및 암호 TLS 인증서 및 키 SSH 키 데이터베이스 또는 내부 서버 이름과 같은 기타 중요한 데이터 일반 ​​문자열 또는 이진 콘텐츠 (최대 500kb 크기)


답변

.env파일 이 주어지면 :

DB_NAME=foo
DB_USER=bar
DB_PASSWORD=baz

그리고이 mongo-init.sh파일 :

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' }] });"

이것은 docker-compose.ymladmin 데이터베이스와 admin 사용자를 생성하고, admin 사용자로 인증 한 다음 실제 데이터베이스를 생성하고 실제 사용자를 추가합니다 :

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: