Created: 2020-09-19 14:58 Updated: 2020-09-19 14:58

Há alguns dias atrás, eu precisei fazer um teste simples no trabalho: enviar um dump de um banco de dados em PostgreSQL para um cliente da empresa restaurá-lo na sua infraestrutura. Até aí, nada de estranho. Eu só gostaria de testar a restauração do dump antes de enviá-lo para o cliente, pois o dump era de um banco da versão 11.6 do PostgreSQL, enquanto que o cliente possuía a versão 10.x do PostgreSQL.

O problema é que, na distribuição Debian instalada no meu computador de trabalho, a versão disponível do PostgreSQL é a 11.6. Eu poderia baixar o código-fonte do PostgreSQL-11.6 e compilá-lo, ou então tentar encontrar um pacote da versão desejada a instalá-la, mas isso nem sempre é uma tarefa fácil.

Pensei então em usar um container com o PostgreSQL. Isso me daria a oportunidade de aprender um pouco mais desta tecnologia e também me permitiria remover tudo no final do teste, sem deixar nenhum vestígio no sistema operacional.

Foi assim que comecei...

Instalando o Docker no Debian

A primeira coisa a fazer é remover alguns pacotes originais do Debian:

sudo apt-get purge docker lxc-docker docker-engine docker.io

Depois, é preciso instalar algumas dependências:

sudo apt-get install apt-transport-https ca-certificates curl \
    gnupg2 software-properties-common

O próximo passo é instalar a chave de autenticação dos pacotes do Docker no gerenciador de pacotes do Debian:

curl -fsSL https://download.docker.com/linux/debian/gpg | \
    sudo apt-key add -

Adicione o repositório do Docker na lista de repositórios do sistema. Neste caso, observe a versão do Debian onde o Docker será instalado e substitua no comando. No exemplo, eu usei a versão Buster:

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian buster stable"

Por fim, atualize a lista de pacotes e instale o Docker:

sudo apt update
sudo apt install docker-ce

Inicie o Docker e verifique se tudo ocorreu sem problema:

sudo systemctl start docker
sudo systemctl status docker

Instalando a imagem no Docker

A instalação da imagem do PostgreSQL no Docker é simples:

sudo docker pull postgres:10.11

Crie um diretório para o armazenamento dos dados dos bancos:

sudo mkdir -p /home/docker/volumes/postgresql-10.11

Liste as imagens disponíveis no Docker:

sudo docker image ls

Execute a imagem do PostgreSQL:

sudo docker run --rm --name postgresql-10.11 -e POSTGRES_PASSWORD=docker \
    -d -p 5432:5432 \
    -v /home/docker/volumes/postgresql-10.11:/var/lib/postgresql/data \
    postgres:10.11

Observação: na próxima execução, remover a opçao --name.

Os parâmetros usados no comando são os seguintes:

Conexão ao container

Uma vez que o container esteja em execução, a conexão ao PostgreSQL em execução no container é idêntica à uma conexão um banco PostgreSQL. A única observação é que deve ser observada porta utilizada. Exemplo:

psql -h localhost -U postgres -d postgres

Para verificar a versão do PostgreSQL, use o comando a seguir enquanto conectado ao PostgreSQL:

SELECT version();

A título de exemplo, os comandos a seguir criam o banco de dados testedb, o usuário usuario (senha senha) e concede todos os privilégios sobre o banco testedb ao usuário (use o comando psql para conectar-se ao banco):

CREATE DATABASE testedb ENCODING 'UTF-8';
CREATE USER "usuario" WITH PASSWORD 'senha';
GRANT ALL PRIVILEGES ON DATABASE testedb TO "usuario";
ALTER ROLE "usuario" WITH LOGIN;

Como conectar a um container em execução

Liste os containers em execução:

sudo docker container ls

Conecte-se ao container desejado:

sudo docker exec -it CONTAINERID bash

Para sair do shell, use a sequência de teclas: CTRL-D.

Consultas ao Docker Hub

Para instalar o PostgreSQL na versão que eu precisava (ou mais pŕoxima), precisei descobrir quais versões estavam disponíveis o hub do Docker. Escrevi então um pequeno programa em Python que pode ajudar:

    #!/usr/bin/env python3

    import json
    import requests
    import sys

    if __name__ == '__main__':

        if len(sys.argv) < 2:
            print('Missing image name, example postgres')
            exit(1)
        #
        name = sys.argv[1]

        url = f'https://registry.hub.docker.com/v1/repositories/{name:}/tags'

        res = requests.get(url)
        if res.status_code == 200:
            print(f'Available images for {name:}:')
            images = json.loads(res.content)
            print('{:5s} {}'.format('Layer', 'Name'))
            for img in images:
                print('{:5s} {}'.format(img['layer'], img['name']))
            #
        else:
            print('Response error: {}'.format(res.status_code))
        #
    #

Para usar este pequeno programa, especifique o nome do container na linha de comando, como no exemplo a seguir:

./docker-list-tags-on-hub.py postgres
Available images for postgres:
Layer Name
    latest
    10
    10-alpine
    10-beta1
    10-beta1-alpine
    10-beta2
    10-beta2-alpine
    10-beta3
    10-beta3-alpine
    10-beta4
    10-beta4-alpine
    10-rc1
    10-rc1-alpine

    (... conteúdo omitido ...)

É isso, espero ter ajudado alguém.