Implantação (Deployment)
Deployment, refere-se ao processo de disponibilizar uma aplicação ou sistema para uso em um ambiente específico, geralmente em produção. É o estágio em que o código e os recursos desenvolvidos são transferidos de um ambiente de desenvolvimento/teste para um ambiente onde os usuários finais podem acessá-los e utilizá-los.
Ambientes de Deployment:
- Desenvolvimento (Development): Onde o código é escrito e testado por desenvolvedores.
- Teste/QA (Quality Assurance): Onde o código é testado para verificar sua funcionalidade.
- Produção (Production): O ambiente final onde a aplicação está acessível para os usuários.
Algumas Configurações extras:
# Essa chave é usada internamente pelo Django para Atribuir cookies e outros aspectos de segurança, em geral. Ela é gerada quando um projeto Django é criado.
SECRET_KEY = 'django-insecure-f^0f9p^qtv&qcy4xtdp_)v(elasdkiouyiiuyyehik7i$39-dkp1h*0f##'
# Caso mude o nome de sua pasta principal é necessário alterar
ROOT_URLCONF = 'projeto.urls'
# Define o idioma padrão do projeto Django. Esse idioma será usado para traduções automáticas (como mensagens de validação de formulários) e outros recursos localizados.
LANGUAGE_CODE = 'pt-br'
# Determina o fuso horário padrão do projeto. Ele é usado para armazenar e exibir datas e horários ('UTC', Horário Universal Coordenado)
TIME_ZONE = 'America/Sao_Paulo'
# Ativa ou desativa a funcionalidade de internacionalização no projeto. Com ela ativada, o Django poderá traduzir textos de acordo com o idioma configurado em LANGUAGE_CODE. Se não for usar desative, pois deixa a aplicação um pouquinho mais rapida
USE_I18N = True
# Define se o Django deve usar fuso horário consciente (timezone-aware) para armazenar datas e horários no banco de dados. Quando ativado, as informações de data e hora serão tratadas no padrão UTC e convertidas automaticamente para o fuso configurado.
USE_TZ = True
'''
Essas configurações abaixo fazem a tradução automática de um projeto.
O uso de USE_I18N = True, permite o uso de funções de tradução como gettext e o comando makemessages para criar arquivos de tradução.
'''
USE_I18N = True
# # Define o caminho onde o Django deve procurar os arquivos de tradução (.po e .mo).
LOCALE_PATHS = [
# Cria um caminho absoluto para a pasta locale na raiz do projeto.
BASE_DIR / 'locale',
]
MIDDLEWARE = [
# ... restante dos middlewares
# Detectar automaticamente o idioma do usuário, geralmente pelo cabeçalho Accept-Language do navegador.
'django.middleware.locale.LocaleMiddleware',
]
obs.: O middleware é uma camada intermediária que processa tanto a requisição quanto a resposta em uma aplicação Django. Ele é útil para realizar verificações, transformações e outras operações antes de a requisição chegar à view ou a resposta ser enviada de volta ao cliente.
| Traduzir textos automaticamente
.po via makemessages. compilar os arquivos .po em .mo com o comando compilemessages. (Baixar GetText Windows).po e edite-os (na parte msgstr) em locale/pt_BR/LC_MESSAGES/django.po:#: .\app\caminho\do\arquivo\template.html:66msgid "Servings"msgstr ""USE_I18N = True
# # Define o caminho onde o Django deve procurar os arquivos de tradução (.po e .mo).
LOCALE_PATHS = [
# Cria um caminho absoluto para a pasta locale na raiz do projeto.
BASE_DIR / 'locale',
]
MIDDLEWARE = [
# ... restante dos middlewares
# Detectar automaticamente o idioma do usuário, geralmente pelo cabeçalho Accept-Language do navegador.
'django.middleware.locale.LocaleMiddleware',
]
Essas configurações fazem a tradução automática de um projeto. O uso de USE_I18N = True, permite o uso de funções de tradução como gettext e o comando makemessages para criar arquivos de tradução.
<!-- Carrega a tag de tradução do django -->
{% load i18n %}
<!-- Traduz textos diretamente no template -->
<h1>{% trans "Bem-vindo ao meu site" %}</h1>
<p>
<!-- Traduz variáveis -->
{% blocktrans with nome=usuario.nome %}
Bem-vindo, {{ nome }}!
{% endblocktrans %}
</p>
O {% load i18n %} é uma tag do Django Template Language (DTL) que carrega o módulo de tradução internacional para o template.
from django.utils.translation import activate
def minha_view(request):
activate('pt-br') # Força o idioma para português do Brasil
return render(request, 'meu_template.html')
# -- ATUALIZAR O IDIOMA DO HTML - pelo contexto -- #
from django.utils import translation
def minha_view(request):
html_language = translation.get_language()
return render(request, 'meu_template.html', {'html_language': html_language})
# No template faça <html lang="{{ html_language }}">
# -- TRADUZINDO CODIGO PYTHO -- #
from django.utils.translation import gettext as _
# toda vez que rodar makemessages, o Django procura todos os _()
print(_("Hello World"))
# -- TRADUZINDO MODELS COM LAZY -- #
from django.utils.translation import gettext_lazy as _
from django.db import models
class Livro(models.Model):
titulo = models.CharField(max_length=100, verbose_name=_('Título'))
autor = models.CharField(max_length=100, verbose_name=_('Autor'))
class Meta:
verbose_name = _('Livro')
verbose_name_plural = _('Livros')
active: Quando o Django renderiza o template dentro dessa view, ele irá traduzir todos os textos marcados para tradução ({% trans %} ou _('texto')) para português do Brasil, independentemente do idioma atual da sessão ou do navegador. Após o término da view, o idioma volta ao que estava antes.
Comandos Tradução
$ django-admin makemessages -l pt_BR # Lê todos os arquivos do projeto que não estão ignorados procurando por traduções
$ python manage.py makemessages -l "pt_br" -i '.venv' -i 'requirements.txt' # mesma coisa do comando acima, mas ignora todos os arquivos da pasta venv e o arquivo requirements
$ django-admin compilemessages # depois de editado/concluída a tradução compile, gerará um arquivo .mo
$ python manage.py compilemessages -l "pt_br" -i '.venv' -i 'requirements.txt' # mesma coisa do comando acima.
Deploy Linux - Nginx e Gunicorn
Configuração voltada para Google Cloud Platform (mas serve para qualquer servidor linux).
- Crie uma instancia no menu Computer Engine.
- Adicione uma chave SSH para acessar o seu servidor a partir de seu computador local, indo em Computer Engine > Metadados > Chaves SSH > Editar > Adicionar Item, e cole sua chave publica gerada em seu computador local.
Nginx é um servidor web e proxy reverso de alto desempenho, ele fica de frente para o mundo, protege o app, facilita balanceamento de carga, serve estáticos e gerencia HTTPS. "Um proxy reverso é um servidor intermediário que recebe requisições de usuários e repassa essas requisições para outra aplicação interna, como um app Django ou Streamlit que está rodando na porta 8000 ou 8501, por exemplo."
master-worker uma arquitetura de processo que o Nginx utiliza, e é uma das chaves para seu alto desempenho e estabilidade. Em resumo o master Controlar e Monitorar e o worker processa as requisições.Master carrega o arquivo nginx.conf e cria os processos Worker (sendo possivel recarregar o arquivo, com o comando reload, sem derrubar o sewrvidor). No Nginx, cada conexão que chega é designada para um dos Workers (cada um usa um nucleo do processador).Workers são processos que atendem as requisições dos clientes. Cada worker é independente e pode atender múltiplas conexões simultaneamente (número de Workers pode ser configurado). Cada worker gerencia de forma assíncrona (event-driven) essas conexões que recebem do master. ps aux | grep nginx gera algo como:
Gunicorn (Green Unicorn) é um servidor de aplicações WSGI para aplicações Python. Ele executa o código Python da sua aplicação Django/Flask. Fica escutando requisições HTTP e repassa para o seu app Python.O Nginx recebe o tráfego, decide pra onde vai a solicitação (se for arquivos estáticos entrega direto sem precisar chamar o gunicorn) e o gunicorn executa o app. O Gunicorn carrega seu app, recebe requisições HTTP, executa o código da aplicação e gera as respostas. Só responde a quem se conectar a ele (normalmente o Nginx, que está na frente, recebendo as requisições do cliente).

-
Buffers de leitura: armazenam o que chega do cliente (por exemplo, cabeçalhos).
-
Buffers de escrita: armazenam o que será enviado ao cliente, enquanto o NGINX espera a melhor forma de transmitir (otimizando por TCP).
Detalhes de configurações mais avançadas em: Ngnix Configurações
Comandos acesso chave ssh
Para acessar o servidor externamente é necessário uma chave ssh que pode ser copiada com: cat C:\Users\Diogo/.ssh/id_ed25519.pub. Lembre-se que a pasta .ssh deve existir dentro da pasta do seu usuário para que seja possível criar a chave SSH. Muito comum ocorrer erros no Windows por falta dessa pasta.
$ ssh-keygen # cria uma chave ssh em seu computador
$ ssh usuario@IP_OU_HOST # Usa a chave do caminho padrão
$ ssh-keygen -t rsa -b 4096 -f CAMINHO+NOME_DA_CHAVE # caso queira usar outras chaves além das que foram geradas em seu computador
$ ssh IP_OU_HOST -i CAMINHO+NOME_DA_CHAVE # se conecta ao servidor usando a chave com caminho personalizado
Comandos preparar servidor
Após acessar o servidor configure-o para hospedar o django. Verifique o que será usado antes de aplicar esses comandos.
$ # O -y serve para responder yes para tudo.
$ sudo apt update -y # atualiza lista de pacotes e suas versão no repositório
$ sudo apt upgrade -y # Instala as atualizações disponíveis para os pacotes já instalados
$ sudo apt autoremove -y # Remove pacotes e dependências que não são mais usados (mantém o sistema limpo)
$ timedatectl list-timezones # lista de timezones
$ sudo timedatectl set-timezone America/Sao_Paulo # Definir timezone
$ sudo apt install build-essential -y # Instala ferramentas de compilação C/C++ (gcc, g++, make)
$ sudo apt install python3.9 python3.9-venv python3.9-dev -y # Instala Python 3.9, suporte a venv e headers para compilação de libs Python
$ sudo apt install libpq-dev -y # Instala bibliotecas de desenvolvimento para PostgreSQL (libpq)
$ sudo apt install git
$
$ # Para https (ceriticado de segurança)
$ sudo apt install certbot python3-certbot-nginx -y # Instala Certbot e integração com Nginx para SSL via Let's Encrypt
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
$ sudo systemctl stop nginx
$ sudo certbot certonly --standalone -d ____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____
$ sudo chmod -R 755 __PROJECT_FOLDER__
$
$ # Após configurar o git e puxar o repositório crie o ambiente virtual e instale os pacotes necessários
$ cd ~/app_repo/nome-do-app.git
$ git pull origin main
$ python3.9 -m venv venv
$ source .venv/bin/activate
$ pip install -r requirements.txt
$ pip install psycopg2
$ pip install gunicorn
| Instalação e Configuração do Nginx
/usr/sbin/: Os arquivos executáveis do Nginx e suas bibliotecas dependentes ./etc/nginx/: Diretório padrão para as configurações do Nginx./etc/nginx/sites-available/: Armazena todos os arquivos de configuração de sites disponíveis no servidor./etc/nginx/sites-enabled/: Armazena links simbólicos (atalhos) para os sites que estão ativos de verdade./etc/nginx/nginx.conf: Arquivo de configuração principal. Ele define as configurações globais do servidor, como o usuário sob o qual o Nginx será executado, o número de processos de trabalho (worker processes), as configurações de log, e o mais importante, inclui outros arquivos de configuração. É aqui que o Nginx é instruído a carregar as configurações de sites individuais./var/log/nginx/: Logs de acesso e erros do Nginx.server {
listen 80; # Nginx escuta na porta 80
listen [::]:80; # Escuta na porta 80, mas para conexões IPv6
# Informa que ess bloco de server deve lidar apenas com requisições para subdominio.meu-site.com.br
server_name subdominio.meu-site.com.br;
#Mapeamento de rota dentro do nginx
location / {
# Redireciona o tráfego para o serviço interno, encaminhando todas as requisições recebidas esse endereço
proxy_pass http://localhost:8501;
# Envia o host original do cabeçalho para aplicação ($host é uma variável do nginx com o conteúdo do Host)
proxy_set_header Host $host;
# Passa o endereço IP que acessou a aplicação. Útil para logs, saber ip de origem etc.
proxy_set_header X-Real-IP $remote_addr;
# Passa a lista de ip que passaram pelos proxies, o primeiro é o original
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Informa à aplicação se a requisição original foi HTTP ou HTTPS.
proxy_set_header X-Forwarded-Proto $scheme;
# Suporte a WebSocket
# Define HTTP/1.1 que suporta websocket já que NGINX por padrão usa 1.0
proxy_http_version 1.1;
# pede um upgrade para o que estiver na variável (vem no cabeçalho - websocket ou h2c), nesse caso websocket.
proxy_set_header Upgrade $http_upgrade;
# Completa o pedido de upgrade
proxy_set_header Connection "upgrade";
}
# Caso deseje monitoramento em tempo real
location /nginx_status {
stub_status on; # Ativa o módulo de status do Nginx para essa URL
access_log off; # Desliga o registro de acessos para essa URL (para não poluir os logs)
allow 127.0.0.1; # Permite acesso a essa URL somente do próprio servidor (localhost)
deny all; # Nega o acesso de qualquer outro IP (protegendo a informação)
}
}
Configurações do arquivo de configuração do NGINX para um subdominio ou dominio.
Em location /, todos os caminhos que começam com /, então entram nessa regra de location /, ou seja, caso alguem acesse http://subdominio.meu-site.com.br/ ou http://subdominio.meu-site.com.br/pagina1 essas regras serão aplicadas. Caso deseje que uma rota seja configurada de outra, como por exemplo um serviço do node.js, faria: location /api/ {proxy_pass http://localhost:3000;}.
Toda requisição tem um cabeçalho original (como Host: games.diogomamedio.com.br) que vem de um cliente (navegador), mas o nginx não repassa todos os cabeçalhos automaticamente para sua aplicação, a não ser que você defina (proxy_set_header), caso não envie o host o nginx passará um host generico como localhost ou 127.0.0.1. Passar o cabeçalho pode ser util quando se tem muitas aplicações assim ela saberá qual dominio esta sendo acessado.
location /nginx_status, cria uma rota especial, acessível via http://localhost/nginx_status (apenas localmente), que vai exibir dados de monitoramento do Nginx em tempo real. curl http://localhost/nginx_status para acessar pelo terminal.
# Define o número de workers automaticamente
worker_processes auto;
# Ou defina manualmente se você conhece seu servidor
# worker_processes 4; # Para um servidor de 4 núcleos
events {
worker_connections 1024 ; # Cada worker manipula até 1024 conexões (Sites de alto tráfego use 2048 ou 4096)
use epoll; # Otimização Linux - use o melhor método de evento
multi_accept on; # Aceita múltiplas conexões de uma vez
}
http {
# Mantenha as conexões ativas por mais tempo para reduzir a sobrecarga e evitar fazer Handshake TCP a toda nova solicitação.
keepalive_timeout 65; # Por quanto tempo manter uma conexão aberta aguardando a próxima solicitação
keepalive_requests 100; # quantas requisições sequenciais, com a mesma conexão aberta, o cliente pode fazer até fechar a conexão e refazer o handshake TCP .
# --- Segurança ---
# Oculta a versão do Nginx nas respostas HTTP
server_tokens off;
# Impede o site de ser exibido dentro de iframes de outros sites (protege contra clickjacking)
add_header X-Frame-Options DENY;
# Força o navegador a sempre usar HTTPS, válido por 1 ano para domínio e subdomínios
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Otimize o serviço de arquivos
sendfile on; # Usa o kernel para servir arquivos diretamente
tcp_nopush on; # junta pacotes de um arquivo grande para enviar de uma vez.
tcp_nodelay on; # Evita o atraso no envio de pacotes pequenos;
# Configurações de buffer - evite desperdício de memória
client_body_buffer_size 128k; # Limita a memória para corpo da requisição (em caso de um post de cliente)
client_header_buffer_size 1k; # Limita em 1k memória para cabeçalhos pequenos.
large_client_header_buffers 4 4k; # Caso o cabeçalho seja grande demais ele usará cabeçalhos de 4k. ( o número 4 significa que pode alocar 4 desses).
}
/logo.png, /style.css, /script.js e etc... Também tem o beneficio do equilibrio de carga, onde, força os clientes a abrirem novas conexões, que podem cair em outros workers, ajudando no balanceamento interno. e impede certas formas de DoS onde o cliente mantém a mesma conexão para sempre.# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
# Basic settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Buffer optimization
client_body_buffer_size 128k;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
# MIME types
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Include your site configurations
include /etc/nginx/sites-enabled/*;
}
Exemplo de configuração inicial sólida que funciona bem para a maioria dos sites.
# Arquivo de configuração principal do Nginx para produção
# Define o usuário que executa os processos do nginx
user www-data;
# Define o número de processos workers como automático baseado nos núcleos da CPU
worker_processes auto;
# Limita o número máximo de arquivos que cada worker pode abrir (aumentado para 65535)
worker_rlimit_nofile 65535; # Aumenta o limite de descritores de arquivos
# Caminho do arquivo PID onde o nginx armazena o ID do processo principal
pid /run/nginx.pid;
# Bloco de configurações de eventos/conexões
events {
# Número máximo de conexões simultâneas por worker
worker_connections 4096; # Aumentado de 1024 para 4096
# Define o método de manipulação de eventos mais eficiente para Linux
use epoll;
# Permite que o worker aceite múltiplas conexões simultaneamente
multi_accept on;
# Desativa o mutex para aceitar conexões - melhora o desempenho em cargas altas
accept_mutex off; # Melhor desempenho sob alta carga
}
# Bloco principal de configurações HTTP
http {
# Permite o envio direto de arquivos via kernel, evitando o buffer do nginx
sendfile on;
# Agrupa pacotes para enviar menos pacotes grandes de uma vez
tcp_nopush on;
# Envia os pacotes imediatamente sem esperar encher o buffer
tcp_nodelay on;
# Tempo que a conexão TCP permanece aberta em idle (sem tráfego)
keepalive_timeout 30; # Reduzido para 30s para liberar conexões ociosas mais rápido
# Número máximo de requisições por conexão antes dela ser fechada
keepalive_requests 1000; # Aumentado para melhor eficiência
# --------------------------
# Buffers e limites
# --------------------------
# Buffer para o corpo da requisição (ex: POST)
client_body_buffer_size 256k;
# Buffer para cada cabeçalho HTTP
client_header_buffer_size 4k;
# Buffer para cabeçalhos grandes - permite até 8 buffers de 8k cada
large_client_header_buffers 8 8k;
# Tamanho máximo permitido para o corpo de uma requisição
client_max_body_size 50m;
# --------------------------
# Timeouts
# --------------------------
# Tempo máximo para o cliente enviar o corpo da requisição
client_body_timeout 12;
# Tempo máximo para o cliente enviar os cabeçalhos
client_header_timeout 12;
# Tempo limite para o nginx enviar a resposta ao cliente
send_timeout 10;
# --------------------------
# Compressão Gzip
# --------------------------
# Habilita compressão gzip para reduzir o tamanho dos arquivos enviados
gzip on;
# Inclui o cabeçalho "Vary: Accept-Encoding" para avisar proxies sobre gzip
gzip_vary on;
# Define o tamanho mínimo de arquivo para ser comprimido (em bytes)
gzip_min_length 1024;
# Define os tipos MIME que podem ser comprimidos
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# --------------------------
# Logs detalhados
# --------------------------
# Define um formato de log detalhado incluindo tempos de resposta e upstream
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
# Define o arquivo de acesso com o formato detalhado, buffer de 32k e flush a cada 5 segundos
access_log /var/log/nginx/access.log detailed buffer=32k flush=5s;
# Define o nível de log de erros para warning (avisos)
error_log /var/log/nginx/error.log warn;
}
Aqui está uma configuração de nível de produção que pode lidar com milhares de usuários simultâneos.
Comandos Nginx
$ sudo apt install nginx -y # Instala o servidor web NGINX.
$ sudo nano /etc/nginx/sites-available/subdominio.meu-site.com.br # Cria um arquivo de configuração para um dominio ou subdomínio.
$ sudo ln -s /etc/nginx/sites-available/subdominio.meu-site.com.br /etc/nginx/sites-enabled/ # ativa as configurações criando um link para o NGINX lê.
$ sudo chmod 755 /home/nome-usuario # da permisão para acesso aos arquivos estáticos para o nginx servir
$ sudo unlink /etc/nginx/sites-enabled/default # Desabilita link simbolico padrão
$ sudo nginx -t # Testa o conjunto inteiro da configuração do NGINX (se há erro de sintaxe, portas erradas etc)
$ sudo systemctl reload nginx # Recarrega o NGINX com a nova config
$ sudo systemctl status nginx # Verifica o status (ex.: se está rodando)
$ sudo systemctl restart nginx # Reinicia o serviço
$ # MONITORAMENTO
$ ps aux | grep nginx # verificar os processos de master e workers rodando
$ sudo netstat -tlnp | grep nginx # verificar as conexões dos workers
$ watch "ss -tuln | grep :80" # checa conexões ativas em tempo real
$ tail -f /var/log/nginx/access.log | pv -lr > /dev/null # monitora requisições por segundo
$ htop -p $(pgrep nginx | tr '\n' ',' | sed 's/,$//') # Verifica o numero de recursos do work
$ tail -f /var/log/nginx/error.log | grep -E "(error|warn|crit)" # Monitora erros em tempo real
$ grep "502" /var/log/nginx/access.log | tail -20 # monitora padrões de erros especificos
$ netstat -an | grep :80 | wc -l # Conta as conexões ativas
$ journalctl -u nginx --since "1 hour ago" # comando linux que verifica logs do nginx da ultima hora.
$ awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20 # listar os IPs que mais fizeram requisições ao seu servidor, em ordem decrescente.
$ # VERIFICA RECURSOS DO SISTEMA
$ iostat -x 1 # Disco I/O
$ free -h # Memória utilizada
$ top -p $(pgrep nginx) # Nginx process usage
server {
listen 80;
listen [::]:80;
server_name ____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html index.php;
# ATTENTION: __STATIC_FOLDER_PATH__
location /static {
autoindex on; # expoe os arquivos estaticos para ser acessado externamente (pelo navegador)
alias __STATIC_FOLDER_PATH__;
}
# ATTENTION: __MEDIA_FOLDER_PATH__
location /media {
autoindex on; # expoe os arquivos estaticos para ser acessado externamente (pelo navegador)
alias __MEDIA_FOLDER_PATH__;
}
# ATTENTION: __SOCKET_NAME__
location / {
proxy_pass http://unix:/run/__SOCKET_NAME__;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# Evita exposição de arquivos de configuração ou ocultos que podem conter informações sensíveis.
location ~ /\.ht {
deny all;
}
location ~ /\. {
access_log off;
log_not_found off;
deny all;
}
gzip on;
gzip_disable "msie6";
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_proxied any;
gzip_types
text/plain
text/css
text/js
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
image/svg+xml;
access_log off;
#access_log /var/log/nginx/____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____-access.log;
error_log /var/log/nginx/____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____-error.log;
}
-
____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____= Seu dominio/subdominio -
__PROJECT_FOLDER__= Caminho da pasta do projeto -
__STATIC_FOLDER_PATH__= Caminho da pasta de arquivos estáticos -
__MEDIA_FOLDER_PATH__= Caminho da pasta de arquivos de midias -
__SOCKET_NAME__= Replace with your unix socket name
# HTTP
server {
listen 80;
listen [::]:80;
# Tamanho maximo de arquivos que podem ser upado
client_max_body_size 20M;
server_name ____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____;
return 301 https://$host$request_uri; # redirecionamento de HTTP (porta 80) para HTTPS(443)
}
# HTTPS
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name ____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____;
ssl_certificate /etc/letsencrypt/live/____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____/chain.pem;
# Improve HTTPS performance with session resumption
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
# Enable server-side protection against BEAST attacks
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
# Disable SSLv3
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# Diffie-Hellman parameter for DHE ciphersuites
# $ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
ssl_dhparam /etc/ssl/certs/dhparam.pem;
# Enable HSTS (https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security)
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
# Enable OCSP stapling (http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox)
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html index.php;
# ATTENTION: __STATIC_FOLDER_PATH__
location /static {
autoindex on;
alias __STATIC_FOLDER_PATH__;
}
# ATTENTION: __MEDIA_FOLDER_PATH__
location /media {
autoindex on;
alias __MEDIA_FOLDER_PATH__;
}
# ATTENTION: __SOCKET_NAME__
location / {
proxy_pass http://unix:/run/__SOCKET_NAME__;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
location ~ /\. {
access_log off;
log_not_found off;
deny all;
}
gzip on;
gzip_disable "msie6";
gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_proxied any;
gzip_types
text/plain
text/css
text/js
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
image/svg+xml;
access_log off;
#access_log /var/log/nginx/____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____-access.log;
error_log /var/log/nginx/____REPLACE_ME_WITH_YOUR_OWN_DOMAIN____-error.log;
}
O arquivos a seguir são templates padrão do GUNICORN que podem ser substituidos conforme a sua aplicação.
-
___GUNICORN_FILE_NAME___→ Nome do socket e serviço -
__YOUR_USER__→ Usuário do servidor -
__PROJECT_FOLDER__→ Pasta do projeto -
__WSGI_FOLDER__→ Pasta onde está owsgi.py
Comandos Gunicorn
$ sudo nano /etc/systemd/system/nome-app.socket # cria um arquivo socket de comunicação com o Ngnix.
$ sudo nano /etc/systemd/system/nome-app.service # Configura o serviço Gunicorn
$ # Ativando
$ sudo systemctl start ___GUNICORN_FILE_NAME___.socket # Inicia o socket do Gunicorn para escutar conexões
$ sudo systemctl enable ___GUNICORN_FILE_NAME___.socket # Configura para o socket iniciar automaticamente no boot do servidor
$ # Checando
$ sudo systemctl status ___GUNICORN_FILE_NAME___.socket # Mostra o status atual do socket (ativo, inativo, erro, etc.)
$ curl --unix-socket /run/___GUNICORN_FILE_NAME___.socket localhost # Faz uma requisição de teste diretamente ao socket Unix para verificar se o Gunicorn está respondendo
$ sudo systemctl status ___GUNICORN_FILE_NAME___ # Exibe o status do serviço associado ao Gunicorn (criado pelo systemd)
$ # Restarting
$ sudo systemctl restart ___GUNICORN_FILE_NAME___.service # Reinicia o serviço Gunicorn (útil após mudanças no código ou config)
$ sudo systemctl restart ___GUNICORN_FILE_NAME___.socket # Reinicia o socket Unix, caso tenha sido alterado ou esteja com problema
$ sudo systemctl restart ___GUNICORN_FILE_NAME___ # Forma genérica para reiniciar diretamente o serviço Gunicorn (se o nome do serviço não tiver extensão)
$ # After changing something
$ sudo systemctl daemon-reload # Recarrega todas as configurações do systemd (necessário após editar arquivos .service ou .socket)
$ # Debugging
$ sudo journalctl -u ___GUNICORN_FILE_NAME___.service # Exibe os logs do serviço Gunicorn (útil para depurar erros)
$ sudo journalctl -u ___GUNICORN_FILE_NAME___.socket # Exibe os logs relacionados ao socket Unix do Gunicorn
[Unit]
Description=gunicorn ___GUNICORN_FILE_NAME___ socket # Descrição do socket para o Gunicorn
[Socket]
ListenStream=/run/___GUNICORN_FILE_NAME___.socket # Caminho do arquivo de socket Unix que será criado
[Install]
WantedBy=sockets.target # Faz o socket iniciar automaticamente no boot junto ao alvo de sockets do systemd
Este arquivo cria um socket Unix que o Gunicorn usará para se comunicar com o Nginx (ou outro proxy reverso). É um "ponto de escuta" no sistema para conexões internas.
[Unit]
Description=Gunicorn daemon for ___GUNICORN_FILE_NAME___ # Descrição do serviço Gunicorn
Requires=___GUNICORN_FILE_NAME___.socket # Este serviço depende do socket correspondente estar ativo
After=network.target # Só inicia após a rede estar disponível
[Service]
User=__YOUR_USER__ # Nome do usuário do sistema que executará o Gunicorn
Group=www-data # Grupo usado normalmente para servidores web
Restart=on-failure # Reinicia automaticamente se o serviço falhar
EnvironmentFile=/home/__YOUR_USER__/__PROJECT_FOLDER__/.env # Arquivo de variáveis de ambiente (opcional)
WorkingDirectory=/home/__YOUR_USER__/__PROJECT_FOLDER__ # Caminho para o diretório do projeto Django
ExecStart=/home/__YOUR_USER__/__PROJECT_FOLDER__/venv/bin/gunicorn \ # Caminho para o executável do Gunicorn dentro da venv
--error-logfile /home/__YOUR_USER__/__PROJECT_FOLDER__/gunicorn-error.log \ # Caminho do arquivo de log de erros
--enable-stdio-inheritance \ # Permite capturar stdout/stderr do app
--log-level "debug" \ # Define o nível de log (debug para desenvolvimento, info ou warning para produção)
--capture-output \ # Captura toda saída do aplicativo para log
--access-logfile - \ # Log de acessos enviado para stdout
--workers 6 \ # Número de processos worker do Gunicorn
--bind unix:/run/___GUNICORN_FILE_NAME___.socket \ # Define o socket Unix que será usado pelo Gunicorn
__WSGI_FOLDER__.wsgi:application # Caminho para o módulo WSGI do Django (ex: projeto.wsgi:application)
[Install]
WantedBy=multi-user.target # Permite que o serviço seja iniciado no modo multi-usuário (produção)
Esse arquivo configura o serviço Gunicorn que roda sua aplicação Django, usando o socket criado para receber requisições.
Assuntos Relacionados
Configurações Banco de Dados
O banco integrado no Django (sqlite), não é bom para aplicações reais, pois, é um banco de dados baseado em arquivo, e não suporta muitas solicitações com velocidade. No entanto a escolha de outro Banco mais Robusto se faz necessária. A razão para optar por um banco SQL ao invés de NOSQL, é que o Django tem sua integração (ORM) com a linguagem SQL.
A Amazon tem um Serviço de Banco de dados Relacional (RDS), onde é possivel configurar o banco de dados da aplicação.
Criar Instancia do RDS
| Descrição |
|---|
| Entre na página do RDS, através da barra de pesquisa |
| No menu lateral clique em Banco de dados (ou Databases) |
| Clique em Criar Banco de Dados |
| Em Modelos (ou Templates), selecione Nível Gratuito (ou Free Tier) |
Renomei o banco em Identificador da instância de banco de dados (ou DB Instance Identifier) algo como: database-django-app |
| Escolha um nome para o usuário master do banco de dados. |
| Em armazenamento você pode desabilitar Escalabilidade automática do armazenamento (ou Enable Store Autoscaling) para nível gratuito |
| Em conectividade, escolha se deseja ou não acesso publico, se clicar em sim, poderá fazer alterações externas do servidor no banco. |
Em Grupo de segurança de VPC (firewall), crie um novo grupo em Criar Novo, e crie um nome como: django-db |
Conclua a operação e após abrir o banco (clicando no nome) vá em Segurança e Conexão copie as informações do endpoint para colocar em seu settings.py. |
Editar Regra de segurança para acesso da aplicação do servidor
| Descrição |
|---|
| Em Segurança e Conexão clique em seu Grupos de segurança da VPC, clique no ID do grupo de segurança e clique em Editar Regras de Entrada (ou edit inbound rules) |
| Selecione a origem para qualquer local-IPv4 (ou anywhere) depois clique em salvar regras |
| Instalando PostgreSQL
instalação Pacote psycopg2
$ pip install psycopg2-binary
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
# Esse nome por padrão é postgres na amazon
'NAME': 'postgres',
'USER': 'diogomamedio',
'PASSWORD': 'minhasenha',
'HOST': 'database-django-blog.cb2a0ose00jd.us-east-1.rds.amazonaws.com',
'PORT': '5432',
}
}
Lembre-se de criar usuário no banco de dados e fazer as migrações.
Servidores Web
Django não é um servidor, é um framework, e fornece um servidor facil e simples para testes local (usando o comando runserver). Por isso é necessário a escolha de um servidor WEB dedicado no ambiente de produção.
Os arquivos asgi.py (Asynchronous Server Gateway Interface) e wsgi.py (Web Server Gateway Interface), estão presentes na pasta principal do projeto e são pontos de entrada que permitem que o servidor de aplicação interaja com o framework Django. Eles são responsáveis por conectar o Django ao servidor web (como Gunicorn, uWSGI, ou Daphne) e definir como as requisições são processadas.
Principais Diferenças entre WSGI e ASGI
| Aspecto | WSGI (wsgi.py) |
ASGI (asgi.py) |
|---|---|---|
| Natureza | Síncrono | Assíncrono |
| Funcionalidades Suportadas | Requisições HTTP tradicionais | HTTP, WebSockets, notificações em tempo real |
| Uso Comum | Aplicações Django convencionais | Projetos modernos com necessidades assíncronas |
| Servidores Suportados | Gunicorn, uWSGI | Daphne, Uvicorn |
Configuração AWS
Criar Perfil da instancia EC2
| Descrição |
|---|
| Na página do IAM, clique em Criar Perfil. |
| Em Tipo de Entidade Confiável, selecione Serviço da AWS. |
| Em Caso de Uso, procure e selecione EC2. |
| Clique em Próximo. |
| Na página de Permissões, procure e anexe as seguintes políticas: |
| - AWSElasticBeanstalkWebTier |
| - AWSElasticBeanstalkWorkerTier |
| - AWSElasticBeanstalkMulticontainerDocker |
Na página de Nome, digite aws-elasticbeanstalk-ec2-role como nome do perfil. |
| Adicione uma descrição (opcional). |
| Clique em Criar Perfil. |
Criar Perfil de serviço
| Descrição |
|---|
| Na barra de pesquisa do console AWS, digite IAM e clique na opção IAM. |
| No menu lateral, clique em Funções ou Roles. |
| Clique em Criar função ou Create role. |
| Em Tipo de Entidade Confiável, selecione Serviço da AWS. |
| Em Caso de Uso, procure e selecione Elastic Beanstalk. |
| Entre as opções exibidas, selecione Elastic Beanstalk Customizable e Elastic Beanstalk. |
| Clique em Próximo. |
| Na página de Permissões, verifique se as políticas abaixo estão selecionadas: |
| - AWSElasticBeanstalkEnhancedHealth |
| - AWSElasticBeanstalkService |
| Clique em Próximo. |
| Na página de Nome, preencha: |
- Nome da função: aws-elasticbeanstalk-service-role |
| - Adicione uma descrição (opcional). |
| Clique em Criar função. |
Criar Aplicação simples em servidor ELASTIC BEANSTALK
| Descrição |
|---|
| Na barra de pesquisa da AWS, escreva Elastic Beanstalk e clique em Criar Aplicação ou Create Application. |
Crie um nome para a aplicação (ex.: django-projeto). |
| Em Plataforma, escolha Python. |
| Em Código da Aplicação, escolha a opção Upload. |
Crie uma pasta no diretório raiz do projeto chamada .ebextensions. Essa pasta é específica para o Elastic Beanstalk. |
Dentro da pasta .ebextensions, crie um arquivo chamado django.config e launch-template.config, e configure-os conforme o exemplo. |
Compacte em ZIP apenas as pastas do projeto que estão na pasta raiz. Não inclua a pasta static (já foi coletada em staticfiles). Faça o upload no campo Código da Aplicação. Imagem A. |
| Em Predefinições, escolha Instância Única (qualificada para o nível gratuito). |
| Clique em Avançar. |
Em Perfil do Serviço, selecione aws-elasticbeanstalk-service-role. Criado anteriormente. |
Em Perfil da Instância EC2, selecione aws-elasticbeanstalk-ec2-role. Criado anteriormente. |
| Continue avançando até chegar às Propriedades de Ambiente (configuração de variáveis). |
Adicione todas as variáveis usadas no arquivo settings.py. Para a variável APP_HOST, insira um valor temporário (XXX). Após a criação da instância, isso poderá ser alterado em configurações. Não inclua "http" ou barras. Imagem B. |
| Clique em Enviar ou continue avançando até que a instância seja criada. |
| Não se importe com possiveis erros. Apenas entre em configuração do ambiente e acesse as variaveis de ambiente para adicionar o endereço criado a sua variável APP_HOST, algo como: meu-blog-django-env.eba-jvy3nnsx.us-east-1.elasticbeanstalk.com |
| Caso queira enviar outra versão basta abrir o ambiente (clicando no nome) e clicar em Fazer Upload e Implantar. As vezes pode ser necessario alterar a versão abrindo a aplicação e selecionando a versão desejada. |
Imagem A Imagem B


Esse Arquivo informa ao servidor elastic beanstalk que as solicitações recebidas devem ser encaminhadas para o arquivo wsy.py.
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: meu_site.wsgi:application
aws:elasticbeanstalk:environment:proxy:staticfiles:
/static: staticfiles
/arquivos: uploads
aws:elasticbeanstalk:application:environment:
DJANGO_SETTINGS_MODULE: meu_site.settings
PYTHONPATH: /var/app/current
container_commands:
01_migrate:
command: "source /var/app/venv/*/bin/activate && python manage.py migrate"
leader_only: true
meu_site é o nome da pasta principal de seu projeto, onde contém um arquivo wsgi.py. Atenção aos espaços para não digitar errado.
option_settings:
aws:autoscaling:launchconfiguration:
DisableIMDSv1: true
aws:ec2:instances:
InstanceTypes: t2.micro
aws:elasticbeanstalk:environment:
EnvironmentType: SingleInstance
aws:autoscaling:asg:
MinSize: 1
MaxSize: 1
Algumas vezes para funcionar pode ser necessário criar um arquivo Procfile na Pasta Raiz.
web: gunicorn --bind 0.0.0.0:8000 meu_site.wsgi:application
Servidor de Arquivos
Existem duas opção para servir arquivos estáticos via web fora do Django (que usa urls.py - opção mais amadora), com um servidor de arquivos especifico, no mesmo servidor da aplicação, como Nginx ou Apache, ou com um servidor dedicado (separado) que é especilista nesse tipo de serviço.
| Servir Arquivos Estáticos em Servidor dedicado
O S3 (Simple Storage Service) é um serviço da amazon para armazenamento de arquivos com recursos avançados de segurança, escalabilidade e distribuição global.. Um Bucket é como um container ou pasta raiz para armazenamento de arquivos na nuvem. Se um HD fosse o S3, um bucket seria como uma pasta raiz ou unidade (C:, D:, etc.), os arquivos e pastas dentro do bucket seriam como subpastas e arquivos.
Siga os passos abaixo para configura-lo:
| Descrição |
|---|
| Na barra de pesquisa digite e abra S3. |
| Clique em Criar Bucket ( que é como uma nova pasta). Onde é possivel pode escolher o nome único global (ex. meuapp-django). |
| Em Configurações de bloqueio do acesso público desmarque Bloquear todo acesso público. Isso é feito para permitir uploads de servidores diferentes. |
| Clique em Criar Bucket. |
| Clique no Nome do Bucket e vá em propriedades e vá até Hospedagem de site estático (ou Static website hosting) e clique em editar. |
| Selecione ativar em Hospedagem de site estático e selecione Hospedar um site estático e clique em salvar (insira qualquer pagina para index e erro, não fará diferença) |
Agora clicando em permissões vá até a sessão Compartilhamento de recursos de origem cruzada (CORS), clique em editar, cole e salve a configuração do cors.json abaixo. |
Ainda em permissões clique em Política do bucket e em editar cole as configurações de politica do arquivo bucket-policy.json. |
Após essa configuração é necessário configurar o a coleta de arquivos estáticos para que ao coletar ele suba esses arquivos diretamente para o bucket criado (ao invés de ir no botão upload manualmente). O serviço IAM é o responsável por gerenciar acessos e serviços a outros usuários ou aplicativos a um conta AWS.
Conceder ao aplicativo Django, no AWS, acesso ao bucket:
| Descrição |
|---|
| Através da pesquisa clique na página do IAM, e em Grupos de Usuários clique em Criar Grupo. |
| Crie um nome (como django-meuapp-grupo) e em Associar políticas de permissões selecione quais as permições serão aplicadas para os usuários desse grupo. |
| Pesquise e selecione AmazonS3FullAccess (fornece acesso total/completo ao serviço Amazon S3). e clique em Criar Grupo de Usuário. Obs.: Usado apenas nesse exemplo, pois não segue o princípio do "privilégio mínimo" e recomenda-se usar políticas mais restritas. |
| Depois crie um usuário clicando em Usuários e em Criar Usuário. Ao inserir o nome do usuario não marque a caixa de acesso ao console. pois estamos criando credenciais para usar com o S3 na aplicação e precisamos apenas do acesso programático. |
| Marque o Radio Adcionar Usuário ao Grupo e abaixo selecione o grupo que ele deve ser incluído (nesse exemplo django-meuapp-grupo) depois clique em avançar. |
| Por fim clique em criar usuário. |
| Logo após clique no nome do usuário criador e clique em Criar Chave de Acesso. |
| Selecione Command Line Interface (CLI) e clique em Criar Chave de Acesso. Obs.: Essa chave não irá aparecer mais, salve-a com segurança pois cada usuário poderá gerar apenas duas chaves. |
Logo após aconfiguração da AWS, rode o teste_S3_upload.py e configure o django para usar esse serviço, conforme o arquivo settings.py abaixo.
Instalação do Pacote boto3
Esse pacote nos permite mudar a maneira de gerenciamento dos arquivos locais do Django. boto3 é um pacote SDK oficial da AWS para python que nos permite comunicar com os serviços AWS.
$ pip install django-storages boto3
import boto3
from botocore.exceptions import ClientError
import os
def upload_test_file():
# Criar um arquivo de teste
test_file = "test.txt"
with open(test_file, "w") as f:
f.write("Este é um arquivo de teste para o S3")
# Configurações do S3
bucket_name = "django-blog-mamedio"
s3_file_name = "test/test.txt"
# Criar cliente S3
s3_client = boto3.client(
's3',
aws_access_key_id="AKIA34AMDKDSFOLJGQKE",
aws_secret_access_key="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",
region_name="us-east-1"
)
try:
# Tentar fazer upload do arquivo
s3_client.upload_file(test_file, bucket_name, s3_file_name)
print(f"Upload bem sucedido! Arquivo disponível em: https://{bucket_name}.s3.amazonaws.com/{s3_file_name}")
# Tentar fazer download do arquivo
s3_client.download_file(bucket_name, s3_file_name, "test_download.txt")
print("Download bem sucedido! Verifique o arquivo test_download.txt")
except ClientError as e:
print(f"Erro: {e}")
# Limpar arquivos locais
try:
os.remove(test_file)
os.remove("test_download.txt")
except:
pass
if __name__ == "__main__":
upload_test_file()
Rode esse Arquivo para verificar se a comunicação com o S3 está funcionando.
| Exemplo Separando os Uploads dos Statics
Para utilizar uma forma mais segura e personalizada, recomenda-se separar os arquivos upados pelo usuário dos arquivos estáticos da propria aplicação.
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
# Cria uma classe (qualquer nome)
class StaticFileStorage(S3Boto3Storage):
# Sobrescreve a variável que define a pasta para os arquivos estáticos com base na variável criada em settings.py
location = settings.STATICFILES_FOLDER
class MediaFileStorage(S3Boto3Storage):
location = settings.MEDIAFILES_FOLDER
Coloque esse arquivo na pasta raiz do projeto (ao lado de manage.py). O nome do arquivo fica ao criterio do programador.
# O restante do settings.py é o mesmo do exemplo anterior
# Nome qualquer para as pastas que serão criadas (automaticamente ao coletar os arquivos) no Bucket do S3
STATICFILES_FOLDER = "static"
MEDIAFILES_FOLDER = "media"
STORAGES = {
"default": {
"BACKEND": "armazenamentos_personalizados.MediaFileStorage",
},
"staticfiles": {
"BACKEND": "armazenamentos_personalizados.StaticFileStorage",
},
}
INSTALLED_APPS = [
'meu_app',
'storages',
# etc ...
]
# Define o nome do bucket criado no S3 que o django irá se comunicar
AWS_STORAGE_BUCKET_NAME = "meuapp-django"
# Nome da Região do bucket (veja no S3 em Região da AWS)
AWS_S3_REGION_NAME = "us-east-1"
# ID da chave gerada
AWS_ACCESS_KEY_ID = "AKIA34AMDKDSFOLJGQKE"
# Chave secreta gerada
AWS_SECRET_ACCESS_KEY = "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"
# Cria um domínio que é gerado automaticamente pela AWS, que concede acesso aos arquivos armazenados no bucket
AWS_S3_CUSTOM_DOMAIN = f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com"
# Configura o Django para usar o Amazon S3 como armazenamento para arquivos estáticos.
STORAGES = {
# lida com arquivos de mídia (uploads)
"default": {
"BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
},
# Lida com arquivos estáticos (CSS, JS, imagens estáticas)
"staticfiles": {
"BACKEND": "storages.backends.s3boto3.S3Boto3Storage",
},
}
Adicione o pacote storages instalado em INSTALLED_APP para sobrescrever o mecanismo de armazenamento padrão do Django. Após essa configuração a coleta de arquivos será feita diretamente para o servidor S3. STORAGES e DEFAULT são configurações do django que informa como os arquivos devem ser armazenados. nesse caso estamos sobrescrevendo a padrão.
# Antes (armazenamento local dos estáticos): /static/css/style.css -> /seu_projeto/staticfiles/css/style.css
# Depois (S3): /static/css/style.css -> https://seu-bucket.s3.amazonaws.com/static/css/style.css
Rodar em Desenvolvimento Usando S3
O comando --nostatic desativa o servidor de arquivos estáticos que vem embutido no servidor de desenvolvimento do Django e força o Django a usar a configuração de produção (servidor S3) para arquivos estáticos.
$ python manage.py runserver --nostatic
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
Este arquivo é feito para aplicar no CORS do servidor (S3) e serve para quando é necessário permitir que seus recursos (como imagens, arquivos estáticos, etc.) sejam acessados de diferentes origens.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::meuapp-django/*"]
}]
}
Permite acesso público de leitura (PublicReadGetObject). Permite a ação s3:GetObject (baixar/visualizar arquivos). Se aplica a todos os objetos no bucket django-blog (indicado por /* no final do Resource). Permite acesso a qualquer usuário ("Principal": "*"). Lembre-se de substituir meupp-django pelo nome real do seu bucket S3 quando for usar esta política.
| Servir Arquivos Estáticos no mesmo servidor
Essa opção apesar de estar no mesmo servidor da aplicação, usa o servidor de arquivos especifico como Nginx ou Apache. Deve ser criado um arquivo static-files.config para direcionar o servidor a usar o Nginx para servi-los.
option_settings:
aws:elasticbeanstalk:environment:proxy:staticfiles:
/static: staticfiles
/files: uploads
Esse arquivo deve ser colocado na pasta .ebextensions do servidor Amazon. staticfiles e upload são as pastas que foram definidas para servir em settings.py e static e files são as urls publicas definidas. Dessa forma qualquer solicitação para essas pastas não será atendida pela aplicação Django mas pelo meu servidor Nginx.
Variáveis de ambiente
Variáveis de ambiente são configurações armazenadas no sistema operacional para uso em aplicações. Permite que você armazene informações sensíveis (senhas, chaves de API) fora do código-fonte, evitando exposição acidental. além de manter a praticidade, fornecendo uma maneira de configurar aplicações sem modificar o código-fonte quando muda o ambiente (desenvolvimento, produção).
O método getenv é usado para obter o valor de uma variável de ambiente no sistema. Ele é fornecido pelo módulo os em Python.
from os import getenv
# Se estiver no ambiente de desenvolvimento ativo o debug
DEBUG = getenv("IS_DEVELOPMENT", True)
ALLOWED_HOSTS = [
# Escolho um nome para configurar o servidor
getenv("APP_HOST","localhost")
]
Retorna o valor da variável especificada ou um valor padrão se ela não existir (nesse caso, retorna True, pois no local não foi definido essa variável). Atenção para a variável no servidor, que provavelmente pode ser uma string, então ao colocar "False", na verdade retornará verdadeiro.
| DotEnv Django
Configurações das variáveis de ambiente em três arquivos, um para desenvolvimento e dois para produção.
import os
import sys
from dotenv import load_dotenv
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
load_dotenv()
# resto do código ...
No django em ambiente de desenvolvimento, é interessante carregar as variáveis de ambiente dentro do manage.py, pois como é o ponto de partida do django, ele já carrega essas variáveis.
import os
from django.core.wsgi import get_wsgi_application
from dotenv import load_dotenv # adicione essa linha
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
load_dotenv() # adicione essa linha
application = get_wsgi_application()
import os
from django.core.asgi import get_asgi_application
from dotenv import load_dotenv # Adicione essa linha
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
load_dotenv() # Adicione essa linha
application = get_asgi_application()
import os
MINHA_VAR = os.environ.get('VAR_NO_DOTENV', 6)
print(MINHA_VAR)
Usando no codigo. retorna valor padrão 6 caso a variável não exista.
# uma variável aleatória para teste
VAR_NO_DOTENV=10
# Django secret key
SECRET_KEY='ib/aU?E.wD\(RAG(x*^{gFq?>kFY(jMr/X\(LY%j-.zigi\vcOmOIw>msiaI`Mfs'
# 0 = False - 1 = True
DEBUG=False
Esses exemplos são para substituir algumas constantes no settings.py.
Código gerador de secret keys (senhas)
Este código gera uma chave, que poderá ser usada, por exemplo, em seu .env para substituir a chave secreta do settings.py.
obs.: remova as aspas.
$ python -c "import string as s;from random import SystemRandom as sr;print(''.join(sr().choices(s.ascii_letters + s.punctuation, k=64)))"
Assuntos Relacionados
Django Debug Toolbar
-
Monitorar e analisar o desempenho das requisições.
-
Verificar todas as consultas SQL executadas (inclusive duplicadas ou lentas).
-
Visualizar variáveis de contexto, sessões, cache, templates renderizados, e muito mais.
-
Detectar N+1 queries (consultas desnecessárias geradas por relações mal feitas).
-
Tempo total da requisição.
-
Todas as queries SQL e o tempo de execução de cada uma.
-
Cabeçalhos HTTP da requisição e resposta.
-
Configuração atual do Django.
-
Variáveis da sessão.
-
Informações sobre o cache.
-
Sinalizadores do template usado.
-
Informações de logs.
Instruções: django debug toolbar