Docker para iniciantes: Criando Containers de Bancos de Dados

jao_dev

João Vitor

Posted on February 17, 2024

Docker para iniciantes: Criando Containers de Bancos de Dados

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Na tag build, informaremos onde se encontra nosso Dockerfile que será usado para configurar o nosso container do Postgres.

    build:
      context: .
      dockerfile: Dockerfile.postgres
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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:
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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/
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

É 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

💖 💪 🙅 🚩
jao_dev
João Vitor

Posted on February 17, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related