Construindo uma API com Java/Spring/Hibernate: configurando banco de dados no Docker
28 October, 2021 - 6 min read
Em um post anterior, comentei sobre minha dificuldade em configurar um banco de dados para usar em ambiente de desenvolvimento. Após muito estudo, encontrei uma forma rápida e eficiente de fazer isso usando a ferramenta Docker.
O Docker é bacana porque permite subir ambientes de desenvolvimento com apenas alguns comandos. No passado, já tive que subir máquinas virtuais e dava bastante trabalho. Precisava instalar diferentes softwares, sempre cuidando para usar as mesmas versões - o que poderia consumir um tempo considerável.
Mesmo assim, por muito tempo o Docker me pareceu um mistério. Não entendia como os comandos faziam todo o trabalho e parecia muito difícil de aprender. Se você estiver buscando material para estudos iniciais, recomendo o livro Docker para desenvolvedores do Rafael Gomes e o livro Descomplicando o Docker do Jeferson Fernando. Essas duas referências me ajudaram muito!
Faz pouco tempo que comecei a usar o Docker com mais frequência e entendo totalmente que, a princípio, a quantidade de conceitos envolvidos na configuração é grande. Mas assim, fique tranquilo, estude bastante - seja nas leituras indicadas ou tutoriais de sua preferência -, pratique em um ambiente que você possa fazer vários testes, que as coisas vão ficando mais claras.
Objetivo
Configurar um banco de dados para desenvolvimento local, usando a ferramenta Docker.
Requisitos
- Ter o docker instalado na máquina. Como fonte de consulta, este vídeo apresenta os passos necessários para a instalação no Windows.
- Ter o projeto Spring criado e aberto na IDE.
Configuração para subir os containers
Com o projeto aberto, crie um arquivo chamado docker-compose.yml na raiz do projeto. Esse arquivo iremos chamar via terminal para que o Docker Compose suba todos os containers que precisamos ao mesmo tempo. Uma vez criado, a estrutura do projeto ficará assim:
Neste exemplo, iremos subir dois containers específicos: o postgres (banco de dados relacional) e o pgadmin (ferramenta de administração do postgres). Existem diversas ferramentas que permitem administrar um banco em ambiente de desenvolvimento (DBeaver, Beekeeper, etc.), a escolha pelo Pgadmin foi para exemplificar que podemos utilizar tudo dentro de containers - em outras palavras, sem a necessidade de instalações locais.
Pois bem, voltando ao arquivo do Compose, ele terá basicamente 3 seções. E aqui, utilizo como referência o livro Descomplicando Docker para a definição de cada uma delas:
- version: versão do Compose utilizada.
- services: os serviços em si que estaremos subindo em forma de container.
- volumes: os volumes utilizados, que foram indicados nos respectivos serviços.
A configuração completa do arquivo ficará parecida com a seguinte:
version: '3'
services:
postgres:
image: 'postgres:9.6-alpine'
volumes:
- postgres-volume:/var/lib/postgresql/data
container_name: "bd-postgres-library"
ports:
- 5433:5432
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: bancoteste
pgadmin4:
image: 'dpage/pgadmin4:5.5'
container_name: "pgadmin4-library"
environment:
PGADMIN_DEFAULT_EMAIL: admin@admin.com
PGADMIN_DEFAULT_PASSWORD: 123
ports:
- 8082:80
volumes:
postgres-volume:
Neste exemplo, o que fizemos foi subir o serviço do banco de dados, definindo um volume para guardar os dados localmente, uma porta de acesso e as variáveis de ambiente. Também, subimos o serviço da "IDE" do banco, definindo porta e variáveis de ambiente (lembrando que as variáveis você pode colocar os valores que preferir). Ah, e definimos um nome para cada container. Caso não sejam definidos nomes, o próprio Docker gera nomes aleatórios.
Uma vez essa configuração feita no arquivo docker-compose.yml, digite o seguinte comando no terminal - dentro da pasta raiz do projeto, onde o arquivo está localizado:
docker-compose up -d
Para verificar se está tudo ok, no terminal também, digite:
docker-compose ps
Aqui, o retorno foi que ambos os containrs estão UP:
Conectar o banco na ferramenta de administração
Já que ambos os containers estão no ar, podemos acessar a URL definida para o Pgdmin (localhost:8082) e logar na ferramenta:
Dentro dela, painel principal, clique em Add New Server e defina as informações para o novo servidor de banco de dados:
- aba General: Nome (de sua preferência).
- aba Connection: Hostname (o nome do serviço do banco definido no docker-compose.yml), Porta, Usuário e Senha - também definidos no arquivo do Compose.
Ao clicar em Save, o servidor estará criado com o banco de dados que definimos nas variáveis de ambiente e pronto para ser utilizado(!)
Configurando o application.properties da aplicação
Por fim, precisamos configurar a fonte de dados (datasource) da aplicação Spring. Basicamente, dizer à aplicação como localizar o banco de dados para que sejam realizadas as operações de consulta, persistência, etc.
Para isso, na IDE, dentro do arquivo src/main/resources/application.properties escrever as seguintes configurações:
# datasource
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5433/bancoteste
spring.datasource.username=postgres
spring.datasource.password=postgres
# jpa
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
Aqui, também realizamos configurações relacionadas ao Hibernate/JPA. Isso certamente pode ser tema para uma outra postagem, o importante é entender que estamos definindo o dialeto do banco de dados utilizado e a estratégia de geração de schemas do banco (neste caso, auto-geração atualizável por parte do Hibernate).
Conclusão
Uma questão importante, antes de finalizar, é que houve uma mudança nos termos de uso do Docker Desktop e, a partir de 31 de janeiro de 2022, seu uso para fins profissionais irá exigir uma licença paga. Ainda assim, de acordo com comunicado da empresa o uso continua gratuito para usos pessoal, educacional e em projetos open-source não comerciais.
Neste post, falei apenas sobre o caminho feliz. Ou seja, pode ser que na hora de subir o ambiente você receba diferentes erros no terminal, o que irá exigir um certo esforço de troubleshooting. O que geralmente faço é tentar interpretar a mensagem de erro, usando um tradutor caso necessário, e buscando no Google qual pode ser a origem do problema. Como são diversas linhas de configuração, são diversas fontes de potenciais erros.
Como mencionei acima, existem muitos conceitos envolvidos e incentivo que você estude e pratique para que tudo faça sentido. Mais importante, para que você se sinta seguro em buscar ajuda e referências, quando necessário realizar configurações em diferentes cenários. Desenvolvimento de software pode parecer uma atividade solitária, mas na verdade envolve muito trabalho em equipe e colaboração.
Até mais!