MongoDB は広く使用されているNoSQLデータベース管理システムであり、スケーラビリティ、高パフォーマンス、柔軟性などのいくつかの機能を提供します。
ただし、 MongoDBを設定するときにユーザーが留意する必要がある重要な側面の 1 つは、認証機能がデフォルトで有効になっていないことです。
つまり、 docker-composeを使用してMongoDB用の新しいコンテナーを作成する場合、認証を手動で有効にして、許可されたユーザーのみがデータベースにアクセスできるようにする必要があります。
しかし、 docker-composeのようなツールを使用して外部依存関係をセットアップすることの要点は、貴重な時間を節約するために可能な限りすべてを自動化することです。
この簡単な記事では、認証を有効にし、 docker-compose を介してカスタム ユーザー/パスを自動的に作成する方法について説明します。
Goで書かれたサンプル プロジェクトを示します。
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ファイルでは、コマンドキーを使用して、コンテナーの起動時にコンテナー内で実行する必要があるコマンドを指定します。 MongoDBコンテナーの場合、コマンド キーの一般的な用途の 1 つは、 --authオプションをmongodプロセスに渡すことによって認証を有効にすることです。
--authオプションが mongod プロセスに渡されると、 MongoDBインスタンスの認証が有効になります。これは、ユーザーがデータベースにアクセスするには、有効な資格情報 (ユーザー名とパスワード) を提供する必要があることを意味します。
認証がなければ、 MongoDBインスタンスにアクセスできる人なら誰でも、機密データにアクセス、変更、または削除する可能性があり、深刻なセキュリティ侵害につながる可能性があります。
./db/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js を実行して、 db/mongo-init.jsファイルをコンテナーにコピーしています。
デシベル/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 ./...
runターゲットによって呼び出されるsetup-dbターゲットは、 MongoDBへの接続を試行し続けるため、メインのGoプログラムは安全に接続を試行できます。
.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
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 }
デシベル/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 に正常に接続されました。」メッセージには、接続できたことが示されています。
$ 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