DEV Community

Cover image for PostgreSQL + Docker = 💙
Bruno de Araujo Alves
Bruno de Araujo Alves

Posted on • Edited on

PostgreSQL + Docker = 💙

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:

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

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

Para listar todos volumes existentes em sua máquina utilize o comando:

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

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

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

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

Página de login do pgAdmin4

Adicione o email e senha passados como variáveis de ambiente na criação do contêiner e clique em "login".

Você será redirecionado para outra página, como esta:

Página inicial pgadmin

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

Criando um novo servidor

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

Modal passo 1

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

Modal passo 2

Verá que o servidor foi criado e agora você tem acesso ao banco de dados do mesmo modo se não estivesse usando docker.

Servidor Criado

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

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

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

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

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

E para remover:

docker-compose rm
Enter fullscreen mode Exit fullscreen mode

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:

Top comments (2)

Collapse
 
dataydes profile image
Daniel Ataydes

Bruno, que bacana, não sabia que dava pra fazer tanta coisa no docker (YAML e persistência) . Valeu pelas dicas.

Collapse
 
devbaraus profile image
Bruno de Araujo Alves

Pois é, tem muita coisinha que dá pra ser feita e as vezes a gente nem percebe. Fico feliz em ter ajudado!