Publicar Django na Zenifra
Este guia leva um projeto Django do repositório GitHub até produção, com arquivos estáticos, banco gerenciado e configurações seguras.
Pré-requisitos
- Projeto Django em um repositório GitHub, com
manage.pyna raiz requirements.txtcomdjango,gunicorn,whitenoisee o driver do banco- Conta GitHub conectada à Zenifra
Django==5.1.1
gunicorn==23.0.0
whitenoise==6.7.0
psycopg[binary]==3.2.2
dj-database-url==2.2.0Os exemplos assumem que o pacote de configuração se chama config (config/settings.py, config/wsgi.py). Troque pelo nome do seu projeto.
Ajuste o settings.py
import os
import dj_database_url
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
DEBUG = os.environ.get("DJANGO_DEBUG", "false").lower() == "true"
ALLOWED_HOSTS = [".clients.zenifra.com"] + [
h for h in os.environ.get("DJANGO_ALLOWED_HOSTS", "").split(",") if h
]
CSRF_TRUSTED_ORIGINS = ["https://*.clients.zenifra.com"] + [
f"https://{h}" for h in os.environ.get("DJANGO_ALLOWED_HOSTS", "").split(",") if h
]
# A Zenifra encerra o HTTPS e informa o protocolo original neste header
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
DATABASES = {
"default": dj_database_url.config(conn_max_age=600, conn_health_checks=True)
}
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
# ... demais middlewares
]
STATIC_URL = "static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
STORAGES = {
"default": {"BACKEND": "django.core.files.storage.FileSystemStorage"},
"staticfiles": {"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage"},
}O WhiteNoiseMiddleware precisa vir logo depois do SecurityMiddleware.
Variáveis de ambiente
| Variável | Exemplo | Para quê |
|---|---|---|
DJANGO_SECRET_KEY | valor aleatório longo | Assinatura de sessões e tokens |
DATABASE_URL | postgres://usuario:senha@host:5432/banco | Conexão com o banco |
DJANGO_ALLOWED_HOSTS | app.minhaempresa.com.br | Domínios personalizados, separados por vírgula |
DJANGO_DEBUG | false | Nunca true em produção |
Gere uma chave com python -c "import secrets; print(secrets.token_urlsafe(50))". As variáveis também existem durante a build, o que permite rodar collectstatic com o settings.py completo.
Configuração no console
| Campo | Valor |
|---|---|
| Runtime | Python 3.12 |
| Porta | 8000 |
pre-build | vazio |
build | python manage.py collectstatic --noinput |
start | python manage.py migrate --noinput && gunicorn config.wsgi --bind 0.0.0.0:8000 --workers 2 --access-logfile - |
Por que migrate no start?
No start, a migration roda com acesso ao banco no ambiente final da aplicação, logo antes de o servidor subir. As migrations do Django usam transações no PostgreSQL, então uma falha não deixa o esquema pela metade.
Uploads de usuários (MEDIA)
Arquivos enviados por usuários não podem ficar no disco efêmero da instância. Escolha um caminho:
- Armazenamento persistente com o diretório
/app/mediaeMEDIA_ROOT = "/app/media". Para servir esses arquivos, use uma view própria ou um serviço de armazenamento de objetos. - Um serviço de armazenamento de objetos compatível com S3, com
django-storages.
Tarefas assíncronas com Celery
Publique o worker do Celery como outro projeto, com o mesmo repositório e o start celery -A config worker --loglevel=info. Use o cache gerenciado ou as filas gerenciadas como broker.
Criar o superusuário
Defina DJANGO_SUPERUSER_USERNAME, DJANGO_SUPERUSER_EMAIL e DJANGO_SUPERUSER_PASSWORD e adicione ao início do start, uma única vez:
python manage.py createsuperuser --noinput || trueDepois que o usuário existir, remova o comando e a variável com a senha.
Problemas comuns
| Sintoma | Correção |
|---|---|
DisallowedHost | Inclua o domínio em ALLOWED_HOSTS ou em DJANGO_ALLOWED_HOSTS |
CSRF verification failed | Inclua https://seu-dominio em CSRF_TRUSTED_ORIGINS |
| CSS e JS retornam 404 | collectstatic não rodou ou o WhiteNoise não está no MIDDLEWARE |
Redirecionamento infinito com SECURE_SSL_REDIRECT | Configure SECURE_PROXY_SSL_HEADER como no exemplo |
KeyError: 'DJANGO_SECRET_KEY' na build | Cadastre a variável no projeto antes de publicar |
too many connections | Reduza --workers ou conn_max_age; veja Problemas de conexão |
Próximos passos
Última atualização em
Python com FastAPI e Flask
Publique APIs Python na Zenifra com FastAPI ou Flask: requirements.txt, uvicorn, gunicorn, workers, porta, migrations com Alembic e erros comuns.
Dockerfiles prontos para Go, Java, PHP e .NET
Dockerfiles testados para publicar Go, Spring Boot, Laravel e ASP.NET Core na Zenifra como imagem OCI, com variáveis de ambiente, porta configurável, build e push.