Restaurando um arquivo SQL num Postgresql dockerizado

Fotos grátis de Namibia

Ao desenvolver uma aplicação com um banco Postgresql em um container, talvez, você precise restaurar um arquivo SQL ou um dump de um banco já existente. É algo simples e aqui está uma sugestão de passo a passo:

Crie o container

Primeiro, crie o container com o Postgresql:

docker run -e POSTGRES_PASSWORD=<senha_de_acesso/> postgres

Inspecione o container

docker inspect <container>

Na saída do comando docker inspect, procure as informações sobre o volume do container. Abaixo segue uma saída de exemplo:

{
    "Type": "volume",
    "Name": "<nome_do_seu_container>",
    "Source": "/var/lib/docker/volumes/<nome_do_seu_container>/_data",
    "Destination": "/<algum_diretorio>",
    "Driver": "local",
    "Mode": "rw",
    "RW": true,
    "Propagation": ""
},

Copie o arquivo SQL

Usando a propriedade source do json acima, copie o arquivo SQL para o volume do container.

cp banco.sql /var/lib/docker/volumes/<nome_do_seu_container>/_data

Restaure o banco

Para restaurar o banco você precisa acessar o container via shell:

docker exec -it <seu_container> bash

Uma vez no container, você pode usar a ferramenta apropriada para restaurar seu banco dependendo do tipo de restore: psql ou pgrestore, por exemplo.

psql -U <usuario> -W -f <path_para_seu_arquivo/banco.sql> banco_de_dados

Pronto :-) Banco restaurado.

Sobre a localização do arquivo SQL

Se você enfrentar alguma dificuldade em encontrar o arquivo, uma ideia é procurar em:

/var/lib/postgresql/data

Referência:

Encontre mais detalhes em https://simkimsia.com/how-to-restore-database-dumps-for-postgres-in-docker-container/

Executando vários serviços num único container

Doca, Recipiente, Exportar, Carga, Frete, Envio, Porto

Docker foi projetado para isolar a execução de serviços, favorecendo assim a extensão, manutenção, etc. das aplicações.

Contudo é possível executar mais de um serviço num único container usando Supervisor. Supervisor é um sistema cliente/servidor que permite controlar processos em sistemas *nix.

O exemplo abaixo cria um container com dois serviços distintos (apenas com código semelhante) executando sob o controle de um supervisor.

Você pode baixar o código em https://github.com/t3rcio/docker-supervisor

Dockerfile

#Dockerfile
FROM python:3.9

ENV PYTHONUNBUFFERED=1

RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor

WORKDIR /code
COPY . /code
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
RUN mkdir logs

RUN supervisord -c /etc/supervisor/conf.d/supervisord.conf &

docker-compose.yml

version: "3.9"

services:
   supervisor:
      build: .
      restart: always
      command: /usr/bin/supervisord
      volumes:
         - .:/code

Coloque esses arquivos num diretório e execute:

user@user-pc:~$ docker-compose -f docker-compose.yml -up

Para verificar a execução dos serviços, execute (também no diretório em que vc executou o container):

user@user-pc:~$ tail -f out1.log
(...)
user@user-pc:~$ tail -f out2.log

Pronto :-) Com essa técnica simples você pode executar vários serviços em um único container; por exemplo, você pode ter um agendador e um consumidor das tarefas agendadas.

Referências

Deploy com GIT

Fazer deploy de aplicações faz parte da rotina de todo desenvolvedor; e dependendo da sua aplicação, pode ser algo que vc queira automatizar. Para isso uma dica que aprendi essa semana é usar o GIT para submeter seu código no servidor; não apenas como um repositório, mas para automatizar os comandos necessários para fazer sua aplicaçao funcionar em ambiente de homologação/produção.

Criando o repositório no servidor

Acesse o servidor que vai receber o deploy usando SSH.

ssh usuario@sevidor.com.br 

Lembre-se de trocar “usuario” e “servidor” por suas credenciais e servidor respectivamente.

Crie o diretório que vai receber os arquivos do deploy.

[usario@servidor]$ mkdir /diretorio/do/deploy

Acesse o diretório criado e inicie um repositório com a opção --bare

[usario@servidor]$ cd /diretorio/do/deploy
[usario@servidor]$ git init --bare .

Nas Referências vc vai encontrar uma explicação mais detalhada, mas em resumo um diretório “bare” é um diretório que apenas recebe os arquivos (ou pushable), i.e. vc não consegue fazer um git add ou um git commit a partir desse diretório. No nosso caso, tal diretório foi criado com --bare porque ele vai apenas receber os arquivos do deploy, não vamos modificar código a partir dele.

Usando o git hooks/post-receive

Depois disso vamos usar git hooks para automatizar o processo de de deploy quando nosso diretório receber um push. Para isso acesse o arquvio post-receive dentro do diretório hooks.

[usario@servidor]$ vim /diretorio/do/deploy/hooks/post-receive

Você pode usar o editor de texto que preferir ;-)

Como conteúdo do arquivo digite os seguinte comandos:

#!/bin/sh
GIT_WORK_TREE=/diretorio/do/deploy git checkout -f

Salve o arquivo e depois conceda permissões de execução.

[usario@servidor]$ chmod 777 /diretorio/do/deploy/hooks/post-receive

O que fizemos foi editar um arquivo que será executado a cada push recebido no diretório. Vc pode inserir outros comandos que sejam usados para deploy; por exemplo cópia de arquivos estáticos, atualização de arquivos do servidor web/aplicação, etc.

Adicionando o repositório deploy

Agora vamos configurar o repositório no nosso projeto que vai receber os pushes para deploy:

git remote add deploy usuario@servidor.com.br:/diretorio/do/deploy

Feito isso, sempre que quiser fazer o deploy basta executar o seguinte comando:

git push deploy master

Será solicitado a sua senha de acesso SSH ao servidor de deploy. No servidor os arquivos serão submetidos e o código no post-receive será executado. Seu deploy estará completo.

Obrigado ao Wesley pelo post no qual aprendi essa facilidade.

Referências

Post em que aprendi o deploy com GITWesley Serafim de Araújo
GIT hooks – ações realizadas pelo GIT ao receber um push
Repositório –bare no GIT – o que é um repositório criado com a opção “–bare”
Diferença entre bare e init – explicação no Stackoverflow sobre a diferença entre repósitórios criados com git init e git init --bare

Arquivos estáticos com wsgi

Um problema que pode surgir ao publicar um site/sistema em Python/Django é a configuração dos arquivos estáticos (imagens, css, scripts, etc).

Para resolver isso o manual do Django orienta o uso das varíaveis STATIC_URL e STATIC_ROOT no settings.py. Você pode encontrar as orientações aqui: https://docs.djangoproject.com/pt-br/3.0/howto/static-files/

Além disso, vc vai precisar configurar o servidor web para servir os arquivos a partir dos paths indicados no settings.py: https://docs.djangoproject.com/pt-br/3.0/howto/deployment/wsgi/modwsgi/#serving-files

Deploy em hospedagens compartilhadas

Contudo, o cenário pode ficar um pouco mais complexo quando não temos acesso aos arquivos de configuração do servidor web, como no caso de hospedagens compartilhadas, por exemplo. Para resolver tal problema a ideia começa a orbitar o wsgi – o arquivo que configura a interfacce entre o servidor web e a aplicação Python/Django. Apesar do manual do Django informar que o framework não serve arquivos estáticos, muitos acreditam que o wsgi pode fazer isso. Para isso há dois pacotes Python que podem ser usados:

Usando o pacote dj-static

No nosso caso vamos usar o dj-static. Instale no seu projeto com:

pip install dj-static

Se vc estiver em um servidor compartilhado, talvez seja necessário instalar o pacote apenas no seu diretório /home. Para isso use a opção --user:

pip install dj-static --user

Feito isso é hora de configurar o seu arquivo wsgi. Veja o exemplo abaixo:

from django.core.wsgi import get_wsgi_application
from dj_static import Cling
(...)
application = Cling(get_wsgi_application())

Para concluir basta acessar o site/sistema para verificar se os arquivos foram estáticos foram servidos. Caso contrário, verifique as variáveis STATIC_URL e STATIC_ROOT no arquivo settings.py do seu projeto.

Você já passou por esse problema em hospedagens compartilhadas? Que solução encontrou?

Referências

WSGI: https://wsgi.readthedocs.io/en/latest/what.html
PEP333 : https://www.python.org/dev/peps/pep-3333/
WSGI no Django: https://docs.djangoproject.com/pt-br/3.0/howto/deployment/wsgi/

Ativando um virtualenv “sem as mãos”

Virtualenv é uma ferramenta fantástica e obrigatória (na minha opinião) para desenvolvimento em Python. Para facilitar ainda mais o processo de desenvolvimento um pacote essencial é o virtualenvwrapper: um “empacotador” (em tradução literal) que permite acessar facilmente os comandos shell relacionados ao ambiente virtual.

Todavia, mesmo com todas essas facilidades surge um problema para rodar aplicações isoladas num virtualenv em produção:

Como ativar automaticamente o ambiente virtual?

Para isso podemos usar o script activate_this.py
Podemos encontrá-lo no seguinte path:

~/.virtualenvs/<seu virtualenv>/bin/activate_this.py

O objetivo desse script é ativar o python do ambiente virtual em questão. Assim, seu ambiente terá acesso às libs necessárias para a sua aplicação rodar sem problemas.

Olha mãe: sem as mãos…!

Para usar o script adicione as linhas abaixo no arquivo que deve iniciar sua aplicação.
Se a sua aplicação rodar em linha de comando (como um serviço do Linux, por exemplo) as linhas abaixo devem ser colocadas no arquivo que inicia a aplicação. Caso seja uma aplicação web a inserção do código abaixo deve ser feita no script carregado pelo servidor web, o wsgi.py,  por exemplo.

activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

Feito isso, reinicie o serviço ou o servidor web.

Pronto! Agora seu ambiente virtual pode ser iniciado automaticamente.

Referências:

Virtualenvwrapper  – Read the docs: https://virtualenvwrapper.readthedocs.io/en/latest/