MongoDB, ölçeklenebilirlik, yüksek performans ve esneklik gibi çeşitli özellikler sunan, yaygın olarak kullanılan bir NoSQL veritabanı yönetim sistemidir.
Ancak kullanıcıların MongoDB'yi kurarken akılda tutması gereken önemli bir husus, kimlik doğrulama özelliğinin varsayılan olarak etkin olmamasıdır.
Bu, docker-compose kullanarak MongoDB için yeni bir kapsayıcı oluşturduğunuzda, yalnızca yetkili kullanıcıların veritabanına erişebildiğinden emin olmak için kimlik doğrulamayı manuel olarak etkinleştirmeniz gerekeceği anlamına gelir.
Ancak docker-compose gibi araçları kullanarak dış bağımlılıklar oluşturmanın asıl amacı, değerli zamandan tasarruf etmek için her şeyi mümkün olduğunca otomatikleştirmektir.
Bu kısa makalede, kimlik doğrulamanın nasıl etkinleştirileceğini ve docker-compose aracılığıyla otomatik olarak özel bir kullanıcı/geçiş oluşturulacağını göreceğiz.
Go'da yazılmış örnek bir proje göstereceğim:
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 dosyasında komut anahtarı, başlatıldığında konteynerin içinde çalışması gereken komutu belirtmek için kullanılır. Bir MongoDB kapsayıcısı için komut anahtarının yaygın kullanımlarından biri, mongod işlemine --auth seçeneğini ileterek kimlik doğrulamayı etkinleştirmektir.
--auth seçeneği mongod sürecine iletildiğinde MongoDB örneği için kimlik doğrulamayı etkinleştirir. Bu, kullanıcıların veritabanına erişmek için geçerli kimlik bilgileri (kullanıcı adı ve parola) sağlamaları gerektiği anlamına gelir.
Kimlik doğrulama olmadan, MongoDB bulut sunucusuna erişimi olan herkes potansiyel olarak hassas verilere erişebilir, bunları değiştirebilir veya silebilir; bu da ciddi güvenlik ihlallerine yol açabilir.
- ./db/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js komutunu çalıştırarak db/mongo-init.js dosyasını konteynere kopyalıyoruz .
db/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 ./...
Çalıştırma hedefi tarafından çağrılan setup-db hedefi, ana Go programının güvenli bir şekilde ona bağlanmayı deneyebilmesi için MongoDB'ye bağlanmaya çalışır.
.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 }
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'ye başarıyla bağlanıldı." mesaj ona bağlanabildiğimizi belirtiyor.
$ 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>
Burada: https://github.com/tiagomelo/docker-mongodb-custom-user-pass