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...
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
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:
- -rm: Automaticamente remove o container e seu sistema de arquivos associado quando for encerrado. Em geral, se nós estamos executando muitos containers de curta duração, é uma boa prática especificar a flag --rm para o comando docker de forma que ele execute a limpeza automática evitando assim problemas de espao em disco. Nós sempre podemos usar o parâmetro -v, descrito a seguir, para persistir os dados para além do ciclo de vida do container;
- -name: Identificação do container. Pode ser utilizado qualquer nome desejado. Note, no entanto, que dois containers não podem ter o mesmo nome, mesmo que não estejam em execução. Para reutilizar um nome, você deve utilizar a flag --rm no comando docker run ou explicitamente remover o container usando o comando docker rm [conteiner];
-e: expõe a variável de ambiente especificada ao container. No exemplo, a variável espceificada (POSTGRES_PASSWORD) define a senha do superusuário do PostgreSQL. O valor de POSTGRES_PASSWORD pode ser qualquer valor, sendo que o valor docker foi utilizado apenas como exemplo e, definitivamente, não é uma senha que deva ser utilizada. Se não for especificada, a senha será a padrão (postgres). Existem outras variáveis de ambiente que podem ser utilizadas no PostgreSQL como, por exemplo POSTGRES_USER e POSTGRES_DB;
- -d: executa o container em segundo plano;
-p: vincula a porta 5432 do host à porta 5432 do container. Esta opção permite às aplicações em execução fora do container comunicarem-se com o servidor PostgreSQL em execução no container;
-v: monta o volume do host no sistema de arquivos interno do container. Isto garante que os dados armazenados pelo PostgreSQL sejam persistentes mesmo após o container ser removido.
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;
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.
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.