paint-brush
MongoDB e Docker-Compose: como ativar um usuário e uma senha personalizados automaticamentepor@tiago-melo
17,554 leituras
17,554 leituras

MongoDB e Docker-Compose: como ativar um usuário e uma senha personalizados automaticamente

por Tiago Melo7m2023/05/09
Read on Terminal Reader

Muito longo; Para ler

[MongoDB](http://mongodb.com/) é um sistema de gerenciamento de banco de dados amplamente utilizado. O recurso de autenticação não é ativado por padrão. Isso significa que os usuários precisarão fornecer credenciais válidas (nome de usuário e senha) para acessar o banco de dados. Veremos como habilitar a autenticação e criar um usuário/pass personalizado automaticamente via [docker-compose]
featured image - MongoDB e Docker-Compose: como ativar um usuário e uma senha personalizados automaticamente
Tiago Melo HackerNoon profile picture

O MongoDB é um sistema de gerenciamento de banco de dados NoSQL amplamente utilizado que oferece vários recursos, como escalabilidade, alto desempenho e flexibilidade.


No entanto, um aspecto importante que os usuários precisam ter em mente ao configurar o MongoDB é que o recurso de autenticação não é ativado por padrão.


Isso significa que, ao criar um novo contêiner para MongoDB usando docker-compose , você precisará habilitar a autenticação manualmente para garantir que apenas usuários autorizados tenham acesso ao banco de dados.


Mas o objetivo de configurar dependências externas usando ferramentas como docker-compose é automatizar tudo o máximo possível para economizar um tempo precioso.


Neste artigo rápido, veremos como habilitar a autenticação e criar um usuário/pass personalizado automaticamente via docker-compose .

Projeto de Amostra

Vou mostrar um projeto de exemplo escrito em Go que:



  • use Javascript para criar o usuário e a senha personalizados para um determinado banco de dados;


  • conecta-se à instância do MongoDB usando as credenciais acima.

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:


Em um arquivo do Docker Compose , a chave de comando é usada para especificar o comando que deve ser executado dentro do contêiner quando ele for inicializado. Para um contêiner MongoDB , um uso comum da chave de comando é habilitar a autenticação passando a opção --auth para o processo mongod .


Quando a opção --auth é passada para o processo mongod, ela habilita a autenticação para a instância do MongoDB . Isso significa que os usuários precisarão fornecer credenciais válidas (nome de usuário e senha) para acessar o banco de dados.


Sem autenticação, qualquer pessoa com acesso à instância do MongoDB poderia acessar, modificar ou excluir dados confidenciais, o que poderia levar a graves violações de segurança.


Estamos copiando o arquivo db/mongo-init.js para o contêiner executando - ./db/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js.

Arquivo de criação de senha/usuário JavaScript do MongoDB

db/mongo-init.js

 db = db.getSiblingDB('sample_db') db.createUser({ user: 'some_user', pwd: 'random_pass', roles: [ { role: 'dbOwner', db: 'sample_db', }, ], });


Makefile

 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 ./...


O destino setup-db , que é invocado pelo destino run , continua tentando se conectar ao MongoDB para que o programa Go principal possa tentar se conectar a ele com segurança.

Conectando ao MongoDB


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


Executando

 $ 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..


O "conectado com sucesso ao MongoDB." mensagem afirma que fomos capazes de nos conectar a ele.

Acesso ao Shell do 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>


Baixe a fonte

Aqui: https://github.com/tiagomelo/docker-mongodb-custom-user-pass