PostgreSQL + Docker = 💙

devbaraus

Bruno de Araujo Alves

Posted on September 13, 2020

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:

💖 💪 🙅 🚩
devbaraus
Bruno de Araujo Alves

Posted on September 13, 2020

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

Sign up to receive the latest update from our blog.

Related

PostgreSQL + Docker = 💙
docker PostgreSQL + Docker = 💙

September 13, 2020