Nesse artigo, vou fornecer alguns exemplos de como criar containers de bancos de dados utilizando Docker.
O foco deste artigo é auxiliar iniciantes no uso do Docker em seus projetos, abordando dúvidas sobre a criação do docker-compose
ou Dockerfile
.
Como referência para os bancos de dados mais populares, utilizei o top 9 da pesquisa do Stack Overflow de 2023.
Sumário
PostgreSQL
No nosso Dockerfile, será bastante simples. Vamos utilizar a imagem do PostgreSQL na versão 16 e expor a porta 5432 para que seja acessível pelo nosso container.
FROM postgres:16
EXPOSE 5432
Vamos adicionar ao nosso services o container do banco de dados e atribuir um nome a ele, neste caso, postgres_db
.
services:
database:
container_name: postgres_db
Na tag build, informaremos onde se encontra nosso Dockerfile
que será usado para configurar o nosso container do Postgres.
build:
context: .
dockerfile: Dockerfile.postgres
No context utilizamos o ponto para indicar que o Dockerfile se encontra no mesmo diretório que o docker-compose.
Como PostgreSQL utiliza o usuário padrão postgres
, adicionaremos apenas uma senha para o nosso usuário na seção environment.
environment:
POSTGRES_PASSWORD: 12345678
Agora precisamos adicionar as portas de comunicação entre a máquina host e o container, isso irá fazer com que tenha uma ligação entre os dois permitindo com que seja possível acessar o banco de dados que foi criado no container.
ports:
- "5432:5432"
A criação de volumes é opcional, mas é algo interessante de se fazer quando estamos utilizando banco de dados, pois permite que ocorra a persistência de dados do nosso container e mesmo que ele seja destruído podemos recriar o container com os dados intactos a partir do volume.
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Por último iremos criar uma Network. Elas são usadas para facilitar a comunicação dos nossos services. Por exemplo, digamos que você deseja criar um Compose que tenha o Postgres e o pgAdmin, para facilitar a interação entre eles, adicionamos ambos na mesma network para ajudar na comunicação (Exemplo aqui).
networks:
- mynet
networks:
mynet:
driver: bridge
Docker-compose
version: '3.8'
services:
database:
container_name: postgres_db
build:
context: .
dockerfile: Dockerfile.postgres
environment:
POSTGRES_PASSWORD: 12345678
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- mynet
volumes:
postgres_data:
networks:
mynet:
driver: bridge
MySQL
Para o Dockerfile do MySQL, faremos a mesma configuração do PostgreSQL, com a diferença de que vamos expor a porta padrão do MySQL.
FROM mysql:8.3
EXPOSE 3306
O docker-compose seguirá a mesma estrutura do compose do Postgres, com a diferença de que na seção environment serão adicionados mais alguns campos além da senha do usuário.
environment:
MYSQL_ROOT_PASSWORD: 12345678
MYSQL_DATABASE: mydb
MYSQL_USER: admin
MYSQL_PASSWORD: admin123
O campo MYSQL_ROOT_PASSWORD
, como o nome sugere, será a senha do usuário root. Não confunda com o campo MYSQL_PASSWORD
, que é a senha do usuário defininda no campo MYSQL_USER
. O campo MYSQL_DATABASE
é o nome do banco de dados que será criado ao construir o container. Você pode criar outros bancos de dados após a criação do container usando comandos do MySQL ou um cliente de banco de dados, como o DBeaver (Exemplo aqui).
Docker-compose
version: '3.8'
services:
database:
container_name: mysql_db
build:
context: .
dockerfile: Dockerfile.mysql
environment:
MYSQL_ROOT_PASSWORD: 12345678
MYSQL_DATABASE: mydb
MYSQL_USER: admin
MYSQL_PASSWORD: admin123
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
networks:
- mynet2
volumes:
mysql_data:
networks:
mynet2:
driver: bridge
SQLite
O SQLite é diferente dos outros bancos de dados mencionados aqui. Ele é um banco de dados disk-based
, o que significa que armazena os dados gerados em um arquivo no próprio sistema e não depende de um servidor, como os outros bancos de dados apresentados. Geralmente, os arquivos são salvos com a extensão .db
.
É amplamente utilizado em aplicações móveis, principalmente no Android, devido à sua presença em muitos dispositivos.
Dockerfile
Para o Dockerfile do SQLite, usaremos uma imagem de uma distribuição Linux chamada Alpine, conhecida por sua leveza, o que a torna uma ótima opção para containers Docker.
FROM alpine:3.19
RUN apk add --no-cache sqlite
WORKDIR /database
Neste Dockerfile, instalamos o SQLite em nosso container e criamos um diretório chamado "database", onde executaremos nossos comandos do SQLite e salvaremos os bancos de dados criados.
Docker-compose
O Compose do SQLite seguirá uma estrutura semelhante ao do Postgres e do MySQL, mas com algumas diferenças.
A primeira diferença está nos volumes, onde vamos explicitar o diretório em que o volume será montado, permitindo uma manipulação mais eficiente dos dados do container.
volumes:
- ./sqlite_data:/database
A segunda diferença é o comando tail -f /dev/null
. Como o SQLite é um banco de dados disk-based
e não possui um servidor para manter o container ativo, usamos este comando para manter o container em execução.
command: ["tail", "-f", "/dev/null"]
O comando tail
é usado para exibir as últimas linhas de um arquivo, enquanto o argumento -f
serve para especificar o arquivo que o comando deverá seguir esperando novas linhas. Ao especificarmos /dev/null
, que não contêm nada, o comando não exibirá nenhum conteúdo no terminal, mantendo assim nosso container ativo para que possamos utilizar os comandos do SQLite no terminal.
version: '3.8'
services:
database:
container_name: sqlite_db
build:
context: .
dockerfile: Dockerfile.sqlite
volumes:
- ./sqlite_data:/database
networks:
- mynet3
command: ["tail", "-f", "/dev/null"]
volumes:
sqlite_data:
networks:
mynet3:
driver: bridge
MongoDB
O MongoDB é um banco de dados NoSQL, diferentemente dos outros apresentados até agora, que eram SQL, ou seja, bancos relacionais. O Mongo é um banco de dados orientado a documentos e é amplamente utilizado por sua flexibilidade, escalabilidade e facilidade de manipulação.
Dockerfile
Nosso Dockerfile seguirá o mesmo padrão dos outros. Utilizaremos a versão latest e iremos expor a porta padrão do MongoDB, que é 27017
.
FROM mongo:latest
EXPOSE 27017
Docker-compose
No docker-compose do MongoDB, forneceremos duas variáveis de ambiente. A priemira é MONGO_INITDB_ROOT_USERNAME
, para definirmos o usuário root, e a segunda é MONGO_INITDB_ROOT_PASSWORD
, onde adicionaremos a senha deste usuário.
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: 12345678
Também utilizaremos o mongo-express
, que é uma interface web para facilitar a manipulação do Mongo, semelhante ao PgAdmin do PostgreSQL.
mongo-express:
image: mongo-express
Para funcionar corretamente, precisamos informar nas variáveis do mongo-express o usuário e senha que criamos para o MongoDB, além da URL do banco de dados.
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: 12345678
ME_CONFIG_MONGODB_URL: mongodb://admin:12345678@database:27017/
A estrutura da URL é da seguinte forma <Driver>://<user>:<password>@<host>:<port>/
. Como estamos utilizando a URL externamente, usaremos o nome do nosso service do MongoDB, que é database
, Caso vá fazer a conexão dentro do container do Mongo utilizando o mongosh, você terá que substituir o host para localhost
.
Para poder acessar mongo-express, será necessário criar um usuário e senha. Isso será feito através das variáveis ME_CONFIG_BASICAUTH_USERNAME
e ME_CONFIG_BASICAUTH_PASSWORD
.
ME_CONFIG_BASICAUTH_USERNAME: mongo
ME_CONFIG_BASICAUTH_PASSWORD: 123456
É necessário que os services utilizem a mesma network para facilitar a comunicação entre eles.
version: '3.8'
services:
database:
container_name: mongo_db
build:
context: .
dockerfile: Dockerfile.mongo
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: 12345678
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db
networks:
- mynet4
mongo-express:
image: mongo-express
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: 12345678
ME_CONFIG_MONGODB_URL: mongodb://admin:12345678@database:27017/
ME_CONFIG_BASICAUTH_USERNAME: mongo
ME_CONFIG_BASICAUTH_PASSWORD: 123456
depends_on:
- database
ports:
- "8081:8081"
networks:
- mynet4
volumes:
mongo_data:
networks:
mynet4:
driver: bridge
Microsoft SQL Server
O SQL Server, diferentemente dos outros bancos de dados, tem sua imagem é mantida pelo Registro de Contêiner da Microsoft
, em vez do Docker Hub.
Dockerfile
A imagem utilizada é a versão Linux do SQL Server. Para mais informações ou para utilizar uma imagem específica do banco de dados, acesse aqui.
FROM mcr.microsoft.com/mssql/server:2022-latest
EXPOSE 1433
Docker-compose
Diferente dos outros bancos, é necessário utilizar a variável ACCEPT_EULA
para confirmar que aceita os temos do Contrato de Licença do Usuário Final. E na variável MSSQL_SA_PASSWORD
, é necessário seguir a política de senha da Microsoft (veja aqui).
version: '3.8'
services:
database:
container_name: sqlserver_db
build:
context: .
dockerfile: Dockerfile.sqlserver
environment:
ACCEPT_EULA: Y
MSSQL_SA_PASSWORD: Admin123#
ports:
- "1455:1433"
networks:
- mynet5
networks:
mynet5:
driver: bridge
Para mais informações sobre a imagem, instruções e como utilizar os comando do SQL Server, acesse a documentação oficial da Microsoft aqui.
Redis
O Redis, assim como o MongoBD, também é um banco de dados NoSQL. É um banco de dados em memória que utiliza uma estrutura de dados chave-valor e é amplamente utilizado para cache
.
Docker-compose
O Compose do Redis será mais simples. Utilizaremos a tag image
para indicar qual será a imagem que nosso container irá fazer o pull e também exporemos a porta padrão do Redis, que é a 6379
.
image: redis
ports:
- "6379:6379"
No Redis, também podemos personalizar sua configuração através de um arquivo chamado redis.conf
, onde podemos definir, por exemplo, quais endereços ele poderá se conectar, quanto de memória será utilizado, especificar o protocolo que pode ser usado e muitas outras configurações. Veja mais sobre as configurações do Redis aqui.
version: '3.8'
services:
database:
image: redis
container_name: redis_db
ports:
- "6379:6379"
networks:
- mynet6
networks:
mynet6:
driver: bridge
MariaDB
Iremos utilizar a versão 11.2.3
da MariaDB e, assim como o MySQL, iremos expor a porta 3306.
FROM mariadb:11.2.3
EXPOSE 3306
Docker-compose
O docker-compose da MariaDB será semelhante ao do MySQL, tendo como única diferença na envirenment que trocaremos somente o prefixo MYSQL
por MARIADB
.
environment:
MARIADB_ROOT_PASSWORD: 13246578
MARIADB_DATABASE: mydb
MARIADB_USER: admin
MARIADB_PASSWORD: admin123
Também teremos um exemplo de docker-compose utilizando o DBeaver aqui.
version: '3.8'
services:
database:
build:
context: .
dockerfile: Dockerfile.mariadb
environment:
MARIADB_ROOT_PASSWORD: 13246578
MARIADB_DATABASE: mydb
MARIADB_USER: admin
MARIADB_PASSWORD: admin123
ports:
- "3306:3306"
volumes:
- mariadb_data:/var/lib/mysql
networks:
- mynet7
volumes:
mariadb_data:
networks:
mynet7:
driver: bridge
Elasticsearch
O Elasticsearch é mais um banco de dados NoSQL da nossa lista. Ele é muito usado como mecanismo de pesquisa, para análise de logs, análises de negócios e entre outros objetivos.
Para uma melhor experiência, irei criar um container utilizando o Elasticsearch e o Kibana
, que é um plugin de visualização de dados utilizado com o Elastic. Ambos fazem parte da Elastic Stack (ou ELK Stack), que inclui outras ferramentas como o Beats e o Logstash.
Dockerfile
No nosso Dockerfile, iremos utilizar a versão 8.12.1
do Elasticsearch. Também criaremos um diretório onde vamos copiar um script para executar dois comandos necessários para utilizar o Elastic com o Kibana. Por fim, iremos expor a porta padrão do Elasticsearch, que é a 9200.
FROM docker.elastic.co/elasticsearch/elasticsearch:8.12.1
WORKDIR /elastic
COPY setup_elasticsearch.sh /elastic
EXPOSE 9200
Nesse script, iremos executar dois comandos que são necessários. O primeiro é para conseguirmos a senha do usuário elastic
, e o segundo comando será para gerarmos o token do kibana. Basicamente, ambos os comandos estão sendo executados e respondendo que queremos resetar a senha e gerar o token.
#!/bin/bash
echo "y" | /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
echo "y" | /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
A utilização do script é opcional; você pode executar os comandos manualmente pelo terminal do container. Mas, caso deseje utilizar, basta entrar no terminal do container e executá-lo escrevendo
./setup_elasticsearch.sh
.
Docker-compose
O Compose terá algumas variáveis de ambiente diferentes até agora. Vamos utilizar apenas duas para este exemplo, mas vale lembrar que na documentação do Elasticsearch e do Kibana existe várias outras.
Estamos utilizando a variável discovery.type
como "single-node". Por padrão, o Elasticsearch permite que o cluster seja "multi-node", o que permite conectar e juntar vários nós no mesmo cluster.
E a segunda variável de ambiente que vamos utilizar é a ES_JAVA_OPTS
, que define o tamanho inicial da memória heap
que o Elasticsearch pode usar. Neste caso, estamos definindo o tamanho como 1GB.
version: '3.8'
services:
elasticsearch:
build:
context: .
dockerfile: Dockerfile.elastic
container_name: Elasticsearch
environment:
discovery.type: "single-node"
ES_JAVA_OPTS: "-Xms1g -Xmx1g"
ports:
- "9200:9200"
networks:
- mynet8
kibana:
image: docker.elastic.co/kibana/kibana:8.12.1
container_name: kibana
ports:
- "5601:5601"
networks:
- mynet8
networks:
mynet8:
driver: bridge
Oracle
Voltamos aos bancos de dados SQL, e para este exemplo, irei utilizar a versão 23c Free
do banco de dados da Oracle. Encontrar a imagem da Oracle pode ser um pouco mais complicado, pois assim como a Microsoft com o SQL Server, a Oracle também mantêm suas próprias imagens, o que torna um pouco mais difícil de achar e utilizar no Docker. A versão que irei utilizar pode ser encontrada aqui.
Docker-compose
Nosso Compose será simples, sendo necessário informar apenas a senha do nosso usuário nas variáveis de ambiente.
environment:
ORACLE_PWD: 12345678
Você também pode modificar o conjunto de caracteres do banco de dados utilizando a variável ORACLE_CHARACTERSET
, mas é opcional. O valor padrão é definido como AL32UTF8
.
version: '3.8'
services:
database:
image: container-registry.oracle.com/database/free:latest
container_name: oracle
environment:
ORACLE_PWD: 12345678
ports:
- "1521:1521"
volumes:
- "oracle_data:/opt/oracle/oradata"
networks:
- mynet9
volumes:
oracle_data:
networks:
mynet9:
driver: bridge
Para conhecer melhor esse banco de dados, gostaria de deixar alguns links úteis. O Get Started ensina a instalar o Oracle de outras formas e também ensina como se conectar no SQL pelo terminal e também em várias linguagens. O Oracle Database 23c para se aprofundar mais nessa versão. E também o Oracle Container Registry caso queira obter as imagens de outros produtos da Oracle ou até mesmo utilizar outras versões do banco de dados.
Conclusão
Espero que este artigo ajude alguém que está começando e tire algumas dificuldades ao criar seu container Docker, pois criar container de banco de dados é algo que utilizamos muito no nosso dia a dia. Vou deixar aqui o link do repositório com todos os exemplos.
Top comments (1)
Muito produtivo, obrigado por andar para eu poder correr!