PostgreSQL + Docker = 💙
Bruno de Araujo Alves
Posted on September 13, 2020
Assim como várias outra técnologias, o PostgreSQL também disponibiliza sua versão conteinerizada, conhecido como imagem, para ser executada usando Docker. Esta prática de conteinerização possibilita uma configuração rápida de ambientes de desenvolvimento, testes e produção.
Os familiarizados ao SGBD sabem que este tem uma ferramenta gráfica de administração que, por sua vez, também disponibiliza uma imagem gratuita e que pode ser utilizado em qualquer sistema operacional que suporte Docker. E os familiarizados ao Docker sabem que existe uma forma simples de executar vários contêineres, o Docker Compose, utilizando um arquivo YAML.
Será demonstrado neste tutorial:
- 🕛 Criar uma network
- 🕑 Criar um volume
- 🕓 Criar contêineres a partir de imagens
- 🕕 Acessar o banco usando pgAdmin4
- 🕗 Criar arquivo YAML
- 🔗 Links
Portanto, é esperado que você tenha conhecimento básico das tecnologias citadas. Certifique-se de que há instalado em sua máquina o Docker e Docker Compose. Ainda, se atente que todos comandos mostrados neste tutorial são executados utilizando um terminal.
🕛 Criar uma network
Network (rede) são pontes de comunicação que possiblitam à contêineres uma conexão entre eles. Geralmente, criasse uma network quando dois ou mias contêineres têm uma relação e comunicam-se. Portanto, para este caso crie uma network chamada postgres-network utilizando o comando abaixo:
docker network create -d bridge postgres-network
Criado a network que será utilizada nesse tutorial, é possível ver quais outras networks estão sendo utilizadas em sua máquina:
docker network ls
NETWORK ID | NAME | DRIVER | SCOPE |
---|---|---|---|
a8d59bf0f5bb | bridge | bridge | local |
c0beeb145f0d | host | host | local |
d539d7388de2 | postgres-network | bridge | local |
🕑 Criar um volume
Volume é o jeito utilizado no Docker para criar uma armazenamento persistente de dados, ou seja, ao desligar o contêiner os dados continuam existindo.
Para criar um volume utilize o comando abaixo, neste caso será criando um volume chamado postgres-data:
docker volume create --name=postgres-data
Para listar todos volumes existentes em sua máquina utilize o comando:
docker volume ls
DRIVER | VOLUME NAME |
---|---|
local | 2b168382f98fc0280482b760893 |
local | portainer_data |
local | postgres-data |
🕓 Criar contêineres a partir de imagens
Antes de escolher uma imagem docker para utilizar é preciso se atentar à alguns detalhes:
- Imagens docker são construídas em cima de alguma imagem de sistema operacional, geralmente linux, e cada imagem linux tem um tamanho.
- Imagens também têm uma versão, geralmente estes são versões do próprio produto/serviço escolhido, e caso não seja especificado uma versão sempre será instalado a última versão estável.
Tendo os detalhes citados acima em mente, neste tutorial será usado a imagem do PostgreSQL versão 12.4, baseada na imagem linux Alpine de ~ 5MB, e para a imagem do pgAdmin4 você irá usar a última versão estável (mais abaixo). Siga o comando a baixo para criar um contêiner do PostgreSQL:
docker run --name postgres --network=postgres-network -e "POSTGRES_PASSWORD=postgresql" -v postgres-data:/var/lib/postgresql/data -p 5440:5432 -d postgres:12.4-alpine
Nesta única linha foi criado e executado um contêiner, em que:
- --name, especificao nome do contêiner (postgres)
- --network, especificaa rede (postgres_network)
-
-e, especifica a variável de ambiente do contêiner
- POSTGRES_PASSWORD=postgresql, é a variável de ambiente que especificaa senha necessária para ter acesso ao banco de dados.
- -v, especifica o volume utilizado para persistir os dados (postgres-data).
- -p, especificaqual porta será exposta (5440:5432), ou seja, será acessível de fora do docker (utilizar em uma aplicação não conteinerizada).
- -d, especificaque após criado o contêiner seu terminal se separe do contêiner e você consiga utilizando sem ter que iniciar um novo terminal, ou tenha que parar o contêiner.
- postgres:12.4-alpine, por fim o nome da imagem utilizada para criar o contêiner, neste caso a image postgres, versão 12.4 utilizando linux alpine.
É possível ver outras versões de imagens PostgreSQL acessando: https://hub.docker.com/_/postgres
Agora, crie um contêiner utilizando a imagem do pgAdmin4 em sua última versão utilizando o seguinte comando:
docker run --name pgadmin --network=postgres-network -p 15432:80 -e "PGADMIN_DEFAULT_EMAIL=example@example.com" -e "PGADMIN_DEFAULT_PASSWORD=pgadmin1234" -d dpage/pgadmin4
Este comando é muito parecido com o utilizado para criar o contêiner do Postgres. Estão presentes os atributos name, network, p, d, e dessa vez 2 atributos e de variáveis de ambiente:
- PGADMIN_DEFAULT_EMAIL, email de login (example@example.com).
- PGADMIN_DEFAULT_PASSWORD, senha de login (pgadmin1234)
Também, por último se encontra o nome da imagem utilizada para criar o contêiner (dpage/pgadmin4), como pode ver, desta vez não foi passado nenhuma versão especifica, portanto, por padrão é instalado a última versão estável da imagem, outro jeito de especificar a última versão da imagem é usando dpage/pgadmin:latest.
🕕 Acessar o banco usando pgAdmin4
Já que foi criado os dois contêineres é hora de testar se tudo está funcionando como esperado. Primeiro rode o comando abaixo para listar todos os contêineres em execução em sua máquina:
docker ps
Caso os dois contêineres ainda estejam em execução você deve ver algo similar ao mostrado abaixo:
CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS | NAMES |
---|---|---|---|---|---|---|
cdb6a40baab2 | dpage/pgadmin4 | "/entrypoint.sh" | 1 minute ago | Up 2 hours | 443/tcp, 0.0.0.0:15432->80/tcp | pgadmin |
0e4fbee2549d | postgres:alpine | "docker-entrypoint.s…" | 4 minutes ago | Up 2 hours | 0.0.0.0:5440->5432/tcp | postgres |
Usando um navegador acesse http://localhost:15432, repare que a porta é a mesma exposta na criação do contêiner pgadmin (15432).
Adicione o email e senha passados como variáveis de ambiente na criação do contêiner e clique em "login".
- email: example@example.com
- senha: pgadmin1234
Você será redirecionado para outra página, como esta:
Porém, ainda não há nenhum servidor de banco de dados configurado. Para adicionar um novo, clique com o botão direito em cima do "Servers" no canto superior esquerdo, vá em "Create" e em seguinda em "Server..."
Um modal será aberto onde você irá inserir informações sobre o servidor. No campo "name" adicione um nome de sua preferência e clique na aba "Connection".
Nesta dela siga os passos:
- No campo "Host name/address", adicione o nome do contêiner "postgres" (nome do contêiner Postgres).
- No campo "Port" utilize a porta interna do contêiner "5432".
- Deixe o campo "Maintenance database" como está.
- No campo "Username" adicione "postgres".
- No campo "Password" adicione a senha usada como variável de ambiente na criação do contêiner do PostgreSQL ("postgresql").
Ao final, clique no botão "Save".
Verá que o servidor foi criado e agora você tem acesso ao banco de dados do mesmo modo se não estivesse usando docker.
Lembre-se que para acesso interno o host do banco de dados é o nome do contêiner (postgres) e a porta é a interna (5432). Já para acesso externo, como em uma aplicação feita em NodeJS, o host é "localhost" ou "127.0.0.1" e a porta é a porta externa especificada na criação do contêiner (5440).
🕗 Criar arquivo YAML
Todo o passo de criação dos contêineres pode ser feito utilizando um arquivo que por convenção/padrão é chamado docker-compose.yml
e utiliza o Docker Compose como seu gerenciador, além disso adiciona o conceito de stack.
Stack nada mais é que um conjunto de contêineres que tem uma relação entre si, você pode criar quantas stacks quiser. Lembrando que sempre que criar um arquivo docker-compose.yml, a stack será o nome da pasta em que o arquivo está. Ao criar uma network dentro de uma stack o nome desta network terá como prefixo o nome da stack (exemplo logo abaixo).
Portanto, para começar, crie um arquivo com o nome docker-compose.yml dentro de uma pasta nomeada postgres, sendo assim a stack será postgres.
Em seguida, abra o arquivo em um editor de texto de sua preferência e comece adicionando o básico:
version: "3"
networks:
network:
driver: bridge
volumes:
postgres-data:
external: true
Em que há:
- version - versão do Compose.
-
networks - networks a serem criadas dentro da stack.
- network - esta network, como dita antes, será nomeada postgres-network, pois será adicionado o prefixo da stack.
- volumes - volumes (armazenamentos) a serem criadas dentro da stack.
Rearraje o script do contêiner postgres ao arquivo:
version: "3"
services:
postgres-compose:
image: postgres:12.4-alpine
container_name: postgres
environment:
POSTGRES_PASSWORD: "postgresql"
ports:
- "5440:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- network
networks:
network:
driver: bridge
volumes:
postgres-data:
external: true
Como feito antes utilizando o script de uma única linha, será criado um contêiner com o nome "postgres", senha "postgresql", porta "5440:5432", network "postgres-network" (lembre do prefixo), e volume.
Agora é a vez de reescrever script do contêiner do pgadmin:
version: "3"
services:
postgres-compose:
image: postgres:12.4-alpine
container_name: postgres
environment:
POSTGRES_PASSWORD: "postgresql"
ports:
- "5440:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- network
pgadmin-compose:
image: dpage/pgadmin4
container_name: pgadmin
environment:
PGADMIN_DEFAULT_EMAIL: "example@example"
PGADMIN_DEFAULT_PASSWORD: "pgadmin1234"
ports:
- "15432:80"
depends_on:
- postgres-compose
networks:
- network
networks:
network:
driver: bridge
volumes:
postgres-data:
external: true
Também, como no contêiner postgres, está tudo bem parecido com escrito anteriormente utilizando uma única linha. O nome, email, senha, porta e network continuam o mesmo, porém também foi adicionado um atributo novo, depends_on, este permite que o contêiner pgadmin não seja criado/iniciado antes do contêiner postgres ser criado/iniciado.
Porém, antes de executar o arquivo será necessário deletar os contêineres já existente afinal não serão mais utilizados como anteriormente, agora eles pertecerão à uma stack. Primeiro pare os dois contêineres docker stop postgres pgadmin
em seguida os remova docker rm postgres pgadmin
.
Agora, rode o comando para executar o arquivo docker-compose.yml utilizando o Docker Compose:
docker-compose up -d
Este comando faz com que os contêineres configurados no arquivo sejam criandos, caso ainda não exista, e os execute. Ainda, quando algo for alterado no arquivo os contêineres afetados serão reconstruidos.
Em algum momento, caso você queira parar todos os contêineres do arquivo, utilize o comando:
docker-compose down
E para remover:
docker-compose rm
Pessoalmente, gosto de guardar arquivos, scripts e instaladores, pois, estou sempre testando algo novo e algumas vezes isso resulta em ter que formatar o computador. Portanto, já ter um arquivo/script de instalação econimiza bastante tempo, afinal não é preciso ter que ir na internet buscar como configurar ou ter que reconfigurar na mão.
O preguiçoso sempre arruma um jeito de não ter trabalho.
Por fim, agradeço você por ter chegado até aqui, deixe seu comentário e sugestão para os próximos posts, e caso este post tenha te ajudado deixe seu like. 👍
🔗 Links
Site pessoal: baraus.dev
GitHub: @devbaraus
Instagram: @devbaraus
Tutoriais:
Posted on September 13, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.