Pracuję z Dockerem i mam stos z PHP, MySQL, Apache i Redis. Muszę teraz dodać MongoDB, więc sprawdzałem plik Dockerfile pod kątem najnowszej wersji, a także plik docker-entrypoint.sh z MongoDB Dockerhub, ale nie mogłem znaleźć sposobu na skonfigurowanie domyślnej bazy danych, użytkownika / hasła administratora i prawdopodobnie autoryzacji metoda dla kontenera z docker-compose.yml
pliku.
W MySQL możesz ustawić niektóre zmienne ENV, na przykład:
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}
I to ustawi bazę danych i użytkownika / hasło jako root
hasło.
Czy jest jakiś sposób na osiągnięcie tego samego w MongoDB? Czy ktoś ma jakieś doświadczenie lub obejście?
mongodb
docker
docker-compose
ReynierPM
źródło
źródło
Odpowiedzi:
Oficjalny
mongo
obraz jest połączone PR obejmuje funkcjonalność do tworzenia użytkowników i baz danych przy starcie.Inicjalizacja bazy danych rozpocznie się, gdy w
/data/db
katalogu nie ma żadnych danych .Konfiguracja użytkownika administratora
Zmienne środowiskowe kontrolujące ustawienia użytkownika „root” to
MONGO_INITDB_ROOT_USERNAME
MONGO_INITDB_ROOT_PASSWORD
Przykład
Nie musisz / nie możesz używać
--auth
w wierszu poleceń, ponieważ skrypt docker entrypoint.sh dodaje to, gdy istnieją zmienne środowiskowe.Inicjalizacja bazy danych
Obraz zawiera również
/docker-entrypoint-initdb.d/
ścieżkę do wdrażania niestandardowych.js
lub.sh
konfiguracyjnych skryptów, które zostaną uruchomione po zainicjowaniu bazy danych..js
skrypty będą uruchamianetest
domyślnie lubMONGO_INITDB_DATABASE
jeśli zostały zdefiniowane w środowisku.lub
Prosty plik inicjalizacyjny powłoki mongo javascript , który demonstruje konfigurację
container
kolekcji z danymi, rejestrowanie i jak wyjść z błędem (w celu sprawdzenia wyników).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) }
źródło
set -e
nakazujeentrypoint.sh
odczytać zmienne zENV
definicji, więc mogę użyć tego samego podejścia, co w przykładzie z MySQL, mam rację? Jako dodatek do twojej odpowiedzi znalazłem ten PR, w którym najwyraźniej ktoś pracuje nad czymś podobnym do twojej propozycji, wychodząc z innego punktu widzeniaset -e
powoduje, że cały skrypt kończy pracę, gdy polecenie zawiedzie, więc skrypt nie może po cichu zawieść i uruchomić mongo.&&
wszędzie.docker-entrypoint-initdb.d
katalog czyni go rozszerzalnym. Mam nadzieję, że get się połączyłoTutaj kolejne czystsze rozwiązanie przy użyciu
docker-compose
ijs
skryptu.W tym przykładzie założono, że oba pliki (docker-compose.yml i mongo-init.js) znajdują się w tym samym folderze.
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>" } ] } );
Następnie po prostu uruchom usługę, uruchamiając następujące polecenie docker-compose
Uwaga : Kod w folderze docker-entrypoint-init.d jest wykonywany tylko wtedy, gdy baza danych nigdy wcześniej nie została zainicjowana.
źródło
volumes
wpis./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
łączy plik lokalny./mongo-init.js
ze ścieżką kontenera/docker-entrypoint-initdb.d/mongo-init.js
jako tylko do odczyturo
. Więcej informacji na temat korzystania z woluminów można znaleźć tutaj: docs.docker.com/storage/volumesvolumes
opcję i dodaj na przykład bezwzględną ścieżkę domongo-init.js
plikuc:\docker\mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
.Oto działające rozwiązanie, które tworzy
admin-user
użytkownika z hasłem, dodatkową bazą danych (test-database
) oraztest-user
w tej bazie danych.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', }, ], });
Najtrudniejsze było zrozumienie, że pliki * .js były uruchamiane bez uwierzytelnienia. Rozwiązanie uwierzytelnia skrypt jako plik
admin-user
wadmin
bazie danych.MONGO_INITDB_DATABASE admin
jest niezbędna, w przeciwnym razie skrypt zostałby wykonany natest
bazie danych. Sprawdź kod źródłowy docker-entrypoint.sh .źródło
UPD Dzisiaj unikać Docker Swarm, tajemnice i configs. Chciałbym uruchomić go
docker-compose
i.env
plików. O ile nie potrzebuję autoskalowania. Gdybym to zrobił, prawdopodobnie wybrałbym k8s. A hasła do bazy danych, konto root czy nie… Czy naprawdę mają znaczenie, gdy używasz pojedynczej bazy danych w kontenerze niepołączonym ze światem zewnętrznym? .. Chciałbym wiedzieć, co o tym myślisz, ale Stack Overflow prawdopodobnie nie nadaje się dobrze do tego rodzaju komunikacji.MONGO_INITDB_DATABASE
Zmienna może mieć wpływ na obraz Mongo , ale nie utworzy bazy danych. Ta zmienna określa bieżącą bazę danych podczas uruchamiania/docker-entrypoint-initdb.d/*
skryptów . Ponieważ nie możesz używać zmiennych środowiskowych w skryptach wykonywanych przez Mongo, wybrałem skrypt powłoki: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
Alternatywnie możesz przechowywać
init-mongo.sh
w configs (docker config create
) i zamontować za pomocą:configs: init-mongo.sh: external: true ... services: mongo: ... configs: - source: init-mongo.sh target: /docker-entrypoint-initdb.d/init-mongo.sh
A sekretów nie można przechowywać w pliku.
Para z GIST w tej sprawie.
źródło
$(cat "$MONGO_INITDB_ROOT_PASSWORD_FILE")
Powinien zostać zastąpiony$MONGO_INITDB_ROOT_PASSWORD
tymi dniami, ponieważ obraz Mongo już obsługuje sekret za nas. hub.docker.com/_/mongoJeśli ktoś szuka sposobu konfiguracji MongoDB z uwierzytelnianiem
docker-compose
, oto przykładowa konfiguracja z wykorzystaniem zmiennych środowiskowych:version: "3.3" services: db: image: mongo environment: - MONGO_INITDB_ROOT_USERNAME=admin - MONGO_INITDB_ROOT_PASSWORD=<YOUR_PASSWORD> ports: - "27017:27017"
Podczas uruchamiania
docker-compose up
instancja mongo jest uruchamiana automatycznie z włączoną autoryzacją. Będziesz mieć bazę danych administratora z podanym hasłem.źródło
mongo --username admin --password password --host localhost --port 27017
nie mogę się połączyć, ponieważ dzienniki pokazują użytkowników, a baza danych została pomyślnie utworzona. BŁĄD:$ 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 failed
mongo admin --username ADMIN --password PASSWORT
połączyć się ze swoją instancją mongo.mongodb://root:example@localhost/my-db?authSource=admin
Jeśli chcesz usunąć nazwy użytkowników i hasła ze swojego pliku docker-compose.yml, możesz użyć Docker Secrets , oto jak do tego przystąpiłem.
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
Ja korzystam z opcji file: dla moich sekretów, jednak możesz też użyć zewnętrznego: i używać sekretów w roju.
Sekrety są dostępne dla każdego skryptu w kontenerze w / var / run / secrets
Dokumentacja Dockera ma to do powiedzenia na temat przechowywania poufnych danych ...
https://docs.docker.com/engine/swarm/secrets/
Możesz używać wpisów tajnych do zarządzania dowolnymi poufnymi danymi, których kontener potrzebuje w czasie wykonywania, ale nie chcesz przechowywać ich w obrazie ani w kontroli źródła, na przykład:
Nazwy użytkowników i hasła Certyfikaty i klucze TLS Klucze SSH Inne ważne dane, takie jak nazwa bazy danych lub serwera wewnętrznego Ogólne ciągi znaków lub zawartość binarna (do 500 kb)
źródło
Biorąc pod uwagę ten
.env
plik:A ten
mongo-init.sh
plik: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' }] });"
Spowoduje
docker-compose.yml
to utworzenie bazy danych administratora i użytkownika administratora, uwierzytelnienie jako administrator, a następnie utworzenie prawdziwej bazy danych i dodanie prawdziwego użytkownika: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:
źródło