MongoDB и Docker-Compose: как автоматически включить пользовательского пользователя и пароль
9 мая 2023 г.MongoDB — это широко используемый NoSQL a> система управления базами данных, которая предлагает несколько функций, таких как масштабируемость, высокая производительность и гибкость.
Однако при настройке MongoDB пользователи должны помнить об одном важном аспекте: функция проверки подлинности не включена по умолчанию.
Это означает, что при создании нового контейнера для MongoDB с помощью docker-compose, вам потребуется включить аутентификацию вручную, чтобы гарантировать, что только авторизованные пользователи имеют доступ к базе данных.
Но весь смысл настройки внешних зависимостей с помощью таких инструментов, как docker-compose, заключается в том, чтобы максимально все автоматизировать, чтобы сэкономить драгоценное время. .
В этой краткой статье мы увидим, как включить аутентификацию и автоматически создать пользователя/пароль с помощью docker-compose.< /p>
Пример проекта
Я покажу пример проекта, написанного на Go, который:
* использует docker-compose для предоставления MongoDB экземпляр;
* используйте Javascript для создания пользовательского пользователя и пароля для данной базы данных;
* подключается к экземпляру MongoDB, используя указанные выше учетные данные.
docker-compose.yaml
version: "3.9"
services:
mongodb:
container_name: mongodb-sample
image: mongo:latest
restart: always
ports:
- "27017:27017"
volumes:
- mongodb-data:/data/db
- ./db/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js
env_file:
- .env
command: [--auth]
volumes:
mongodb-data:
В файле Docker Compose ключ command используется для указания команды, которая должна выполняться внутри контейнер при запуске. Для контейнера MongoDB одним из распространенных способов использования командного ключа является включение проверки подлинности путем передачи параметра --auth в процесс mongod.
Когда параметр --auth передается процессу mongod, он включает аутентификацию для экземпляра MongoDB. Это означает, что пользователям необходимо будет предоставить действительные учетные данные (имя пользователя и пароль) для доступа к базе данных.
Без аутентификации любой, у кого есть доступ к экземпляру MongoDB, потенциально может получить доступ, изменить или удалить конфиденциальные данные, что может привести к серьезным нарушениям безопасности. р>
Мы копируем файл db/mongo-init.js в контейнер, запустив - ./db/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init. .js.
Файл создания пользователя/пароля MongoDB JavaScript
БД/mongo-init.js
db = db.getSiblingDB('sample_db')
db.createUser({
user: 'some_user',
pwd: 'random_pass',
roles: [
{
role: 'dbOwner',
db: 'sample_db',
},
],
});
Создать файл
SHELL = /bin/bash
DOCKER_MONGODB=docker exec -it mongodb-sample mongosh -u $(ADMIN_USER) -p $(ADMIN_PASSWORD) --authenticationDatabase admin
DOCKER_MONGODB_WITH_CUSTOM_CREDS=docker exec -it mongodb-sample mongosh -u $(DB_USER) -p $(DB_PASS) --authenticationDatabase $(DB_NAME)
.PHONY: help
## help: shows this help message
help:
@ echo "Usage: make [target]"
@ sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /'
.PHONY: setup-db
## setup-db: sets up MongoDB
setup-db: export ADMIN_USER=admin
setup-db: export ADMIN_PASSWORD=f3MdBEcz
setup-db:
@ echo "Setting up MongoDB..."
@ docker-compose up -d mongodb
@ until $(DOCKER_MONGODB) --eval 'db.getUsers()' >/dev/null 2>&1 && exit 0; do
>&2 echo "MongoDB not ready, sleeping for 5 secs...";
sleep 5 ;
done
@ echo "... MongoDB is up and running!"
.PHONY: mongodb-console
## mongodb-console: opens MongoDB console
mongodb-console: export DB_USER=some_user
mongodb-console: export DB_PASS=random_pass
mongodb-console: export DB_NAME=sample_db
mongodb-console:
@ ${DOCKER_MONGODB_WITH_CUSTOM_CREDS}
.PHONY: run
## run: runs the application
run: setup-db
@ go run cmd/main.go
.PHONY: cleanup
## cleanup: removes MongoDB and associated volumes
cleanup:
@ docker-compose down
@ docker volume rm $$(docker volume ls -q)
.PHONY: test
## test: runs unit tests
test:
@ go test -v ./...
Цель setup-db, которая вызывается целью run, продолжает пытаться подключиться к MongoDB< /a>, чтобы основная программа Go могла безопасно подключиться к нему.
Подключение к MongoDB
n .env
MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=f3MdBEcz
MONGODB_DATABASE=sample_db
MONGODB_USER=some_user
MONGODB_PASSWORD=random_pass
MONGODB_HOST_NAME=localhost
MONGODB_PORT=27017
n config/config.go
// Copyright (c) 2023 Tiago Melo. All rights reserved.
// Use of this source code is governed by the MIT License that can be found in
// the LICENSE file.
package config
import (
"github.com/joho/godotenv"
"github.com/kelseyhightower/envconfig"
"github.com/pkg/errors"
)
// Config holds all configuration needed by this app.
type Config struct {
MongoDbUser string `envconfig:"MONGODB_USER"`
MongoDbPassword string `envconfig:"MONGODB_PASSWORD"`
MongoDbDatabase string `envconfig:"MONGODB_DATABASE"`
MongoDbHostName string `envconfig:"MONGODB_HOST_NAME"`
MongoDbPort int `envconfig:"MONGODB_PORT"`
}
var (
godotenvLoad = godotenv.Load
envconfigProcess = envconfig.Process
)
func ReadConfig() (*Config, error) {
if err := godotenvLoad(); err != nil {
return nil, errors.Wrap(err, "loading env vars")
}
config := new(Config)
if err := envconfigProcess("", config); err != nil {
return nil, errors.Wrap(err, "processing env vars")
}
return config, nil
}
db/mongodb.go
// Copyright (c) 2023 Tiago Melo. All rights reserved.
// Use of this source code is governed by the MIT License that can be found in
// the LICENSE file.
package db
import (
"context"
"fmt"
"github.com/pkg/errors"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type MongoDb struct {
database string
client *mongo.Client
}
// For ease of unit testing.
var (
connect = func(ctx context.Context, client *mongo.Client) error {
return client.Connect(ctx)
}
ping = func(ctx context.Context, client *mongo.Client) error {
return client.Ping(ctx, nil)
}
)
// ConnectToMongoDb connects to a running MongoDB instance.
func ConnectToMongoDb(ctx context.Context, user, pass, host, database string, port int) (*MongoDb, error) {
client, err := mongo.NewClient(options.Client().ApplyURI(
uri(user, pass, host, database, port),
))
if err != nil {
return nil, errors.Wrap(err, "failed to create MongoDB client")
}
err = connect(ctx, client)
if err != nil {
return nil, errors.Wrap(err, "failed to connect to MongoDB server")
}
err = ping(ctx, client)
if err != nil {
return nil, errors.Wrap(err, "failed to ping MongoDB server")
}
return &MongoDb{
database: database,
client: client,
}, nil
}
// uri generates uri string for connecting to MongoDB.
func uri(user, pass, host, database string, port int) string {
const format = "mongodb://%s:%s@%s:%d/%s"
return fmt.Sprintf(format, user, pass, host, port, database)
}
cmd/main.go
// Copyright (c) 2023 Tiago Melo. All rights reserved.
// Use of this source code is governed by the MIT License that can be found in
// the LICENSE file.
package main
import (
"context"
"fmt"
"os"
"github.com/pkg/errors"
"github.com/tiagomelo/docker-mongodb-custom-user-pass/config"
"github.com/tiagomelo/docker-mongodb-custom-user-pass/db"
)
func run() error {
ctx := context.Background()
config, err := config.ReadConfig()
if err != nil {
return errors.Wrap(err, "reading config")
}
_, err = db.ConnectToMongoDb(ctx,
config.MongoDbUser,
config.MongoDbPassword,
config.MongoDbHostName,
config.MongoDbDatabase,
config.MongoDbPort,
)
if err != nil {
return errors.Wrap(err, "connecting to MongoDB")
}
fmt.Println("successfully connected to MongoDB.")
return nil
}
func main() {
if err := run(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Запуск
$ make run
Setting up MongoDB..
[+] Running 3/3
⠿ Network docker-mongodb-custom-user-pass_default Created 0.0s
⠿ Volume "docker-mongodb-custom-user-pass_mongodb-data" Created 0.0s
⠿ Container mongodb-sample Started 0.3s
MongoDB not ready, sleeping for 5 secs...
... MongoDB is up and running!
successfully connected to MongoDB..
«Успешное подключение к MongoDB». в сообщении говорится, что мы смогли подключиться к нему.
Доступ к оболочке MongoDB
$ make mongodb-console
Current Mongosh Log ID: 645955b82bcce4a09d59bda3
Connecting to: mongodb://<credentials>@127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&authSource=sample_db&appName=mongosh+1.8.2
Using MongoDB: 6.0.5
Using Mongosh: 1.8.2
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
test> use sample_db
switched to db sample_db
sample_db>
Скачать исходный код
Здесь: https://github.com/tiagomelo/docker-mongodb-custom-user-pass.
Оригинал