Deploy app - Django

 

Criação do droplet


Criação da chave SSH com o Putty

OBS- Pode fazer pelo próprio git, é até mais prático.

Não consegui realizar o login via SSH pois sempre dava negação da chave pública conforme a dúvida no fórum https://www.digitalocean.com/community/questions/permission-denied-after-creating-droplet-using-ssh-keys
Escolher opção password e após a configuração do droplet configurar o openssh para permitir o acesso via SSH

Configuração básica após a criação do droplet


Adicionar as chaves SSH ao servidor

rsync --archive --chown=thiago:thiago ~/.ssh /home/thiago não consegui add ao servidor

Instalação do Nginx



há três perfis disponíveis para o Nginx:

  • Nginx Full: Este perfil abre ambas as portas 80 (tráfego Web normal, não criptografado) e 443 (tráfego TLS/SSL criptografado)
  • Nginx HTTP: Este perfil abre apenas a porta 80 (tráfego Web normal, não criptografado)
  • Nginx HTTPS: Este perfil abre apenas a porta 443 (tráfego TLS/SSL criptografado)


O Nginx funcionará como proxy reverso do Gunicorn


O que é um proxy reverso?
Em uma rede de computadores, um proxy reverso básico fica entre um grupo de servidores e os clientes que desejam usá-los. Cliente é qualquer hardware ou software que pode enviar solicitações para um servidor. Por exemplo, seu navegador da Web é o cliente que você está usando para ler este artigo, hospedado em nossos servidores. O proxy reverso traz todos os pedidos dos clientes para os servidores e também entrega todas as respostas e os serviços dos servidores aos clientes. Do ponto de vista do cliente, isso faz parecer que tudo está vindo de um só lugar.


Para que os proxies reversos são usados?
Os proxies reversos ficam entre clientes e um serviço de rede, como um site. Os três recursos mais importantes que os proxies reversos fornecem são segurança, balanceamento de carga e facilidade de manutenção. Os proxies reversos também podem desempenhar um papel na otimização e identidade visual.

Gerenciando o processo do Nginx


Agora que você tem seu servidor Web em funcionamento, vamos rever alguns comandos básicos de gerenciamento.

Para parar seu servidor Web, digite:

sudo systemctl stop nginx

 
Para iniciar o servidor quando ele estiver parado, digite:

sudo systemctl start nginx

 
Para parar e então iniciar o serviço novamente, digite:

sudo systemctl restart nginx

 
Se você estiver simplesmente fazendo alterações de configuração, o Nginx geralmente pode recarregar sem quedas na conexão. Para fazer isso, digite:

sudo systemctl reload nginx


Configuração


Abra um novo arquivo de configuração no sites-availablediretório do Nginx usando o editor de linha de comando de sua preferência.

sudo vim /etc/nginx/sites-available/your_domain

server {
listen 80;
listen [::]:80;

root /var/www/your_domain/html;
index index.html index.htm index.nginx-debian.html;

server_name your_domain www.your_domain;

location / {
try_files $uri $uri/ =404;
}

}

Em seguida, vamos habilitar o arquivo criando um link dele para o diretório sites-enabled, de onde o Nginx lê durante a inicialização:

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

Em seguida, desvincule o arquivo de configuração padrão do /sites-enabled/diretório:

sudo unlink /etc/nginx/sites-enabled/default

 

Observação : se você precisar restaurar a configuração padrão, poderá fazer isso recriando o link simbólico, como este:

sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/

 
Isso dirá ao Nginx para usar a configuração na próxima vez que for recarregado.


Quando estiver pronto, recarregue o Nginx para aplicar as alterações:

sudo systemctl reload nginx


Redirecionar Nginx para a porta 80




Ler material


como habilitar login remoto mysql [dúvida]

Instalação do pack LAMP



Instalando o phpmyadmin



Agora você pode instalar o phpMyAdmin executando o seguinte comando:

sudo apt install phpmyadmin

 
Durante o processo de instalação, você será solicitado a escolher um servidor web (Apache ou Lighttpd) para configurar. O phpMyAdmin pode fazer automaticamente uma série de alterações de configuração para garantir que funcione corretamente com qualquer um desses servidores web durante a instalação. No entanto, como você está usando o Nginx como um servidor da web, você não deve escolher nenhuma dessas opções. Em vez disso, pressione TAB para destacar <Ok> e pressione ENTERpara continuar o processo de instalação.

Obs- Se necessário for lembrar de ajustar a pasta para onde aponta a url principal para poder localizar o phpmyadmin.

Importando database in mysql

funcionou usando o comando source /home/thiago/database/customer.sql

Criando usuários no mysql



CREATE USER usuario IDENTIFIED BY 'SENHA';
GRANT ALL ON *.* TO 'usuario'@'%';

Alterar a localização padrão do phpMyAdmin.

Mysql


sudo mysql
sudo mysql -r root -p
show databases;
use [data_base];
show tables;
drop database [database]

create database [NAME]/
use [database];
mysql -u username -p new_database < data-dump.sql
mysql -u thiago -p db_django_customer < customer.sql
funcionou usando o comando source /home/thiago/database/customer.sql

mysql -u thiago -p db_customer_django < /home/thiago/database/db_customer_django.sql
mysql -u root -p db_customer_django < /home/thiago/database/db_customer_django.sql

Instalação do Python


Nota: dentro do ambiente virtual, você pode usar o comando python em vez de python3, e pip em vez de pip3 se preferir. Se usar o Python 3 em sua máquina fora de um ambiente, será necessário usar os comandos python3 e pip3 exclusivamente.

Para gerenciar os pacotes de software do Python, vamos instalar o pip, uma ferramenta que irá instalar e gerenciar pacotes de programação que podemos querer usar em nossos projetos. Você pode aprender mais sobre os módulos ou pacotes que você pode instalar com o pip lendo “Como Importar Módulos no Python 3.”

sudo apt install -y python3-pip

Há mais alguns pacotes e ferramentas de desenvolvimento a serem instalados para garantir que teremos uma configuração robusta para nosso ambiente de programação:

sudo apt install -y build-essential libssl-dev libffi-dev python3-dev


Configurando um Ambiente Virtual


Vamos instalar o venv digitando:

sudo apt install -y python3-venv

sudo apt install python3-pip python3-venv (pip e venv)

Instalação do Django Framework


Agora, sempre que você inicia um novo projeto, pode criar um ambiente virtual para ele. Comece criando e movendo para um novo diretório de projeto:

mkdir ~/newproject

cd ~/newproject

Em seguida, crie um ambiente virtual dentro do diretório do projeto usando o pythoncomando que é compatível com sua versão do Python. 
Chamaremos nosso ambiente virtual my_env, mas você deve nomeá-lo com algo descritivo:

python3 -m venv my_env

Para instalar pacotes no ambiente isolado, você deve ativá-lo digitando:

source my_env/bin/activate

Utilizando o requirements.txt


Um jeito simples de criar o seu próprio arquivo de depências é usando o comando pip freeze da seguinte forma:
$ pip freeze > requirements.txt

Um passo comum da configuração de ambientes de desenvolvimento Python é fazer a instalação de dependências. Muitas vezes esse passo é executado da seguinte forma:
$ pip install -r requirements.txt

Caso apresente algum erro ao instalar o mysqlclient:
In order to fix it, I had to run first
sudo apt-get install python-dev default-libmysqlclient-dev

Em seu novo ambiente, você pode usar pippara instalar o Django. Independentemente da sua versão do Python, pipdeve ser chamado apenas pipquando você estiver no seu ambiente virtual. Observe também que você não precisa usar, sudojá que está instalando localmente:

pip install django

 
Você pode verificar a instalação digitando:

django-admin --version

Para evitar ter muitos diretórios aninhados, no entanto, vamos dizer ao Django para colocar o script de gerenciamento e o diretório interno no diretório atual (observe o ponto final):

django-admin startproject djangoproject .

Para migrar o banco de dados, digite:

python manage.py migrate

Finalmente, vamos criar um usuário administrativo para que você possa usar a interface de administração do Djano . Vamos fazer isso com o createsuperusercomando:

python manage.py createsuperuser

Para testar seu aplicativo com sucesso, você precisará modificar uma das diretivas nas configurações do Django.

Abra o arquivo de configurações digitando:

nano ~/django-test/djangoproject/settings.py
 

Dentro, localize a ALLOWED_HOSTS diretiva. Isso define uma lista de endereços ou nomes de domínio que podem ser usados para se conectar à instância do Django. 
Uma solicitação de entrada com um cabeçalho de Host que não está nesta lista gerará uma exceção. 
Django requer que você configure isso para prevenir uma certa classe de vulnerabilidade de segurança.

Entre colchetes, liste os endereços IP ou nomes de domínio que estão associados ao seu servidor Django. 
Cada item deve ser listado entre aspas, com entradas separadas separadas por vírgula. 
Se você deseja solicitações para um domínio inteiro e quaisquer subdomínios, acrescente um ponto antes do início da entrada:

~ / django-test / djangoproject / settings.py

ALLOWED_HOSTS = ['your_server_ip_or_domain', 'your_second_ip_or_domain', . . .]


Testando o Servidor de Desenvolvimento

Depois de ter um usuário, você pode iniciar o servidor de desenvolvimento Django para ver a aparência de um novo projeto Django.
Você só deve usar isso para fins de desenvolvimento. 
Quando estiver pronto para implantar, certifique-se de seguir as diretrizes do Django para implantação com cuidado.

Antes de tentar o servidor de desenvolvimento, certifique-se de abrir a porta apropriada em seu firewall. 

Se você seguiu o guia de configuração inicial do servidor e está usando UFW, pode abrir a porta 8000 digitando:

sudo ufw allow 8000

 
Inicie o servidor de desenvolvimento:


python manage.py runserver your_server_ip:8000

python manage.py runserver 0.0.0.0:8000


Visite o endereço IP do seu servidor seguido por :8000 no seu navegador:

http://your_server_ip:8000



PYTHONPATH=/var/www/customer_django/customer/.. gunicorn --bind 0.0.0.0:8000 customer.wsgi:application

gunicorn --bind 0.0.0.0:8000 customer.wsgi <<< funcionou no mesmo nível do manage.py, lembrar de abrir a porta 8000 de nginx (não esquecer de ativar a virtual env)
sudo ufw allow 8000 <<< abrindo a porta 8000

Reiniciar o servidor após alteração no projeto

pkill gunicorn < matar o processo gunicorn somente se necessário.

sudo service gunicorn restart
sudo service nginx restart # somente se você precisar
sudo service mysql restart
sudo systemctl status gunicorn


// https://caterinadmitrieva.medium.com/serving-multiple-django-apps-on-second-level-domains-with-gunicorn-and-nginx-a4a14804174c
tutorial para usar multiplos apps em um único servidor

// https://www.ryancheley.com/2021/03/07/setting-up-multiple-django-sites-on-a-digital-ocean-server/

So when we want to start gunicorn for this particular app, we will need to run the following commands:
$ systemctl start django_one.socket
$ systemctl start django_one.service #equals to 'start gunicorn'


Abrindo as portas do mysql para conexões externas


sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

Por padrão, esse valor é definido como 127.0.0.1, o que significa que o servidor procurará apenas conexões locais. Você precisará alterar esta diretiva para fazer referência a um endereço IP externo. Para efeitos de resolução de problemas, você poderia definir esta diretiva para um endereço IP curinga, quer *, ::ou 0.0.0.0:

# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = 0.0.0.0


sudo systemctl restart mysql # por fim lembrar de reiniciar o mysql

sudo ufw allow from remote_IP_address to any port 3306 # utilizar apenas dessa forma para o ip específico da máquina.


Ler sobre WSGI


Documentação Gunicorn

Discussão sobre o uso do Gunicorn



Servindo arquivos estáticos





Criando arquivos de socket e de serviço systemd para o Gunicorn


Nós testamos que o Gunicorn pode interagir com nosso aplicativo Django, mas devemos implementar uma maneira mais robusta de começar e parar o servidor do aplicativo. Para isso, vamos fazer arquivos de serviço e de socket do systemd.

O socket Gunicorn será criado no boot e escutará as conexões. Quando ocorrer uma conexão, o systemd irá iniciar o processo Gunicorn automaticamente para lidar com a conexão.

Comece criando e abrindo um arquivo de socket do systemd para o Gunicorn com privilégios sudo:

sudo vim /etc/systemd/system/gunicorn.socket

Dentro, vamos criar uma seção [Unit] para descrever o socket, uma seção [Socket] para definir a localização do socket e uma seção [Install] para garantir que o socket seja criado no momento certo:

/etc/systemd/system/gunicorn.socket

[Unit]
Description=gunicorn socket


[Socket]
ListenStream=/run/gunicorn.sock


[Install]
WantedBy=sockets.target
 
Salve e feche o arquivo quando você terminar.


Em seguida, crie e abra um arquivo de serviço do systemd para o Gunicorn com privilégios sudo no seu editor de texto. O nome do arquivo de serviço deve corresponder ao nome do arquivo do socket com exceção da extensão:

sudo vim /etc/systemd/system/gunicorn.service

Comece com a seção [Unit], que é usada para especificar os metadados e dependências. Vamos colocar uma descrição do nosso serviço aqui e dizer ao sistema init para iniciar isso somente após o objetivo da rede ter sido alcançado. Uma vez que nosso serviço se baseia no socket do arquivo do socket, precisamos incluir uma diretriz Requires para indicar essa relação:

/etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target



/etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=thiago
Group=www-data
WorkingDirectory=/home/thiago/django_app/django <<< essa pasta tem que ser no mesmo diretório do arquivo manage.py
ExecStart=/home/thiago/django_app/my_env/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
djangoproject.wsgi:application

[Install]
WantedBy=multi-user.target






Com isso, nosso arquivo de serviço systemd está completo. Salve e feche-o agora.

Agora, podemos iniciar e habilitar o socket do Gunicorn. Isso criará o arquivo do socket em /run/gunicorn.sock agora e na inicialização do sistema. Quando uma conexão for feita no socket, o systemd irá iniciar o gunicorn.service automaticamente para lidar com ela:

sudo systemctl start gunicorn.socket

sudo systemctl enable gunicorn.socket



// retirar o servico do systemd, caso precise.
// https://superuser.com/questions/513159/how-to-remove-systemd-services
systemctl stop [servicename]
systemctl disable [servicename]
rm /etc/systemd/system/[servicename]
rm /etc/systemd/system/[servicename] # and symlinks that might be related
rm /usr/lib/systemd/system/[servicename]
rm /usr/lib/systemd/system/[servicename] # and symlinks that might be related
systemctl daemon-reload
systemctl reset-failed

 
Podemos confirmar que a operação foi bem sucedida verificando o arquivo do socket.


Verificando o arquivo de socket do Gunicorn

Verifique o status do processo para descobrir se ele foi capaz de iniciar:

sudo systemctl status gunicorn.socket

Se fizer alterações no arquivo /etc/systemd/system/gunicorn.service, recarregue o daemon para reler a definição do serviço e reinicie o processo do Gunicorn digitando:


sudo systemctl daemon-reload

sudo systemctl restart gunicorn


// mysql
sudo less /var/log/mysql/error.log



Static and Media Folder Django Projects with Digital Ocean Spaces




duvida postada na página



ler sem falta sobre automatização de deploy  e sobre a config do spaces
https://www.sayari3.com/articles/19-django-digitalocean-spaces-tutorial/
https://realpython.com/automating-django-deployments-with-fabric-and-ansible/

https://stackoverflow.com/questions/62012392/my-django-app-font-from-digital-ocean-spaces-are-not-working
https://pypi.org/project/django-cors-headers/
https://github.com/adamchainz/django-cors-headers





LER SOBRE INTEGRAÇÃO DO SUPERVISOR






HTTPS


https://newbedev.com/getting-gunicorn-to-run-on-port-80 usa o authbind para direcionar para porta 80



Checklist Deploy





Liberando o mysql para acesso remoto




Passo 1


Passo 2


To GRANT ALL privileges to a user, allowing that user full control over a specific database, use the following syntax:

mysql> GRANT ALL PRIVILEGES ON database_name.* TO 'username'@'localhost';
# nesse ponto temos que nos atentar a conceder os privilégios pra evitar o retorno acess denied for user X on localhost ou ip remoto, por exemplo.



Problemas possíveis

https://weasyprint.readthedocs.io/en/latest/install.html a biblioteca weasyprint precisa da linha

Debian / Ubuntu


You can install it with pip on Debian 10 Buster or newer, or on Ubuntu 18.04 Bionic Beaver or newer, after installing the following packages:

sudo apt-get install build-essential python3-dev python3-pip python3-setuptools python3-wheel python3-cffi libcairo2 libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info














Verificação de uso das portas



netstat -ntlp

sudo lsof -t -i:8000 identifica o número do processo de acordo com a porta informada
Vai mostrar algo assim.
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN 6599/python
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN -
tcp 0 0 192.168.124.1:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN -
tcp6 0 0 :::3306 :::* LISTEN

Portanto, agora apenas feche a porta em que o Django / python já está em execução, eliminando o processo associado a ele.
kill -9 PID

No meu caso
kill -9 6599


Agora execute seu aplicativo Django.










Erros após implantação

https://www.tecmint.com/limit-file-upload-size-in-nginx/



# Discover our IP address
ALLOWED_HOSTS += ip_addresses() ???? segurança ????






Logging de erros


Para resolver uma situação como essa, é melhor ativar o log adicionando a seguinte configuração a settings.py temporário

LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'file': { 'level': 'DEBUG', 'class': 'logging.FileHandler', 'filename': '/tmp/debug.log', }, }, 'loggers': { 'django': { 'handlers': ['file'], 'level': 'DEBUG', 'propagate': True, }, }, }

Depois é só usar o comando:

tail -f django_logs.log
e tente tail -f /tmp/debug.log. e quando você vir seu problema, poderá lidar com isso com muito mais facilidade do que a depuração às cegas.





Material de apoio




Comentários

Postagens mais visitadas deste blog

Weasyprint

Models - Django

Django Mask with JQuery Mask Plugin