- Por Que um VPS é o Ambiente Certo para Python em Produção
- Pré-requisitos Antes de Começar
- Passo 1: Configuração Inicial do Servidor
- Passo 2: Fazer o Deploy da Aplicação
- Passo 3: Testar a Aplicação com Gunicorn
- Passo 4: Criar um Serviço systemd
- Passo 5: Configurar o Nginx como Proxy Reverso
- Passo 6: Configurações Específicas para Django
- Quantos Workers o Gunicorn Precisa?
- Variáveis de Ambiente e Segredos
- Banco de Dados em Produção
- Monitoramento e Logs
- Escolhendo o VPS Certo para Aplicações Python
- FAQs
Hospedar uma aplicação Python em produção é um dos momentos em que o ambiente realmente faz diferença. Shared hosting raramente suporta WSGI corretamente, limita o que você pode instalar e pode derrubar processos longos sem nenhum aviso. Um VPS com acesso root muda esse cenário completamente.
Este guia cobre o processo do início ao fim: da configuração inicial do servidor até sua aplicação Flask ou Django respondendo requisições reais, com Nginx como proxy reverso, Gunicorn como servidor WSGI e systemd mantendo tudo funcionando.
Por Que um VPS é o Ambiente Certo para Python em Produção
Shared hosting foi feito para PHP. Rodar Flask ou Django nele exige gambiarras, versões antigas de Python e zero controle sobre dependências do sistema. Quem já tentou sabe o desgaste.
Em um VPS você tem:
- Acesso root para instalar qualquer versão do Python, criar ambientes virtuais e configurar serviços do jeito que precisar
- Controle total sobre portas e firewall, necessário para expor sua aplicação com segurança
- Processos persistentes gerenciados pelo systemd, que reinicia sua aplicação automaticamente após falhas ou reboots
- NVMe storage, que reduz latência de I/O em operações de banco de dados e leitura de arquivos estáticos
Se você gerencia projetos para clientes ou desenvolve aplicações próprias, um VPS com NVMe em datacenter brasileiro faz diferença mensurável no tempo de resposta para usuários finais no Brasil.
Pré-requisitos Antes de Começar
Você vai precisar de:
- Um VPS com Ubuntu 22.04 ou 24.04 (os exemplos usam Ubuntu)
- Acesso SSH com usuário root ou sudo
- Um domínio apontando para o IP do servidor, ou um IP para testes
- Sua aplicação Flask ou Django funcionando localmente
Passo 1: Configuração Inicial do Servidor
Acesse seu VPS via SSH e atualize o sistema:
apt update && apt upgrade -y
Crie um usuário dedicado para a aplicação. Nunca rode sua app como root:
adduser deploy
usermod -aG sudo deploy
Instale as dependências base:
apt install -y python3 python3-pip python3-venv nginx git
Configure o firewall:
ufw allow OpenSSH
ufw allow 'Nginx Full'
ufw enable
Passo 2: Fazer o Deploy da Aplicação
Mude para o usuário deploy e crie o diretório da aplicação:
su - deploy
mkdir -p /home/deploy/myapp
cd /home/deploy/myapp
Clone seu repositório ou transfira os arquivos via SCP/SFTP. Depois, crie e ative o ambiente virtual:
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Instale o Gunicorn dentro do ambiente virtual:
pip install gunicorn
Passo 3: Testar a Aplicação com Gunicorn
Para Flask
Supondo que seu arquivo principal seja app.py e o objeto Flask se chame app:
gunicorn --bind 0.0.0.0:8000 app:app
Para Django
Dentro do diretório do projeto (onde está o manage.py), rode:
gunicorn --bind 0.0.0.0:8000 meusite.wsgi:application
Substitua meusite pelo nome do seu projeto Django — o diretório que contém o wsgi.py.
Se a aplicação responder no navegador via http://ip-do-servidor:8000, o Gunicorn está funcionando. Encerre o processo com Ctrl+C e siga para a configuração do systemd.
Passo 4: Criar um Serviço systemd
O systemd mantém o Gunicorn rodando em segundo plano e reinicia automaticamente em caso de falha.
Crie o arquivo de serviço:
sudo nano /etc/systemd/system/myapp.service
Cole o conteúdo abaixo, ajustando os caminhos e o comando de bind conforme seu projeto:
[Unit]
Description=Gunicorn para aplicação Python
After=network.target
[Service]
User=deploy
Group=www-data
WorkingDirectory=/home/deploy/myapp
ExecStart=/home/deploy/myapp/venv/bin/gunicorn \
--workers 3 \
--bind unix:/home/deploy/myapp/myapp.sock \
app:app
[Install]
WantedBy=multi-user.target
Para Django, substitua app:app por meusite.wsgi:application.
Ative e inicie o serviço:
sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp
sudo systemctl status myapp
O status deve mostrar active (running). A partir daqui, o Gunicorn se comunica via socket Unix — mais eficiente do que uma porta TCP local.
Passo 5: Configurar o Nginx como Proxy Reverso
O Nginx recebe as requisições HTTP/HTTPS e as repassa ao Gunicorn via socket.
Crie o bloco de servidor:
sudo nano /etc/nginx/sites-available/myapp
server {
listen 80;
server_name seudominio.com.br www.seudominio.com.br;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/deploy/myapp;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/deploy/myapp/myapp.sock;
}
}
Ative o site e teste a configuração:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
Sua aplicação agora responde na porta 80. Para HTTPS, adicione um certificado via Certbot:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d seudominio.com.br -d www.seudominio.com.br
O Certbot configura o redirecionamento HTTP para HTTPS automaticamente e agenda a renovação do certificado.
Passo 6: Configurações Específicas para Django
Django em produção exige alguns ajustes no settings.py:
DEBUG = False
ALLOWED_HOSTS = ['seudominio.com.br', 'www.seudominio.com.br']
STATIC_ROOT = '/home/deploy/myapp/static/'
STATIC_URL = '/static/'
Colete os arquivos estáticos e rode as migrations:
source venv/bin/activate
python manage.py collectstatic
python manage.py migrate
O Nginx serve os arquivos estáticos diretamente, sem passar pelo Gunicorn. Isso reduz a carga no processo Python e melhora o tempo de resposta.
Quantos Workers o Gunicorn Precisa?
A fórmula mais usada é (2 × núcleos de CPU) + 1. Em um VPS com 2 vCPUs, use 5 workers. Com 4 vCPUs, use 9.
Mais workers não significa necessariamente mais performance — cada worker ocupa memória RAM. Se sua aplicação faz muitas operações I/O (chamadas a APIs externas, banco de dados), considere workers do tipo gevent ou uvicorn para aplicações assíncronas:
pip install uvicorn[standard]
gunicorn -w 4 -k uvicorn.workers.UvicornWorker app:app
Isso é especialmente relevante para aplicações FastAPI ou Django com ASGI.
Variáveis de Ambiente e Segredos
Nunca coloque senhas, chaves de API ou SECRET_KEY diretamente no código. Use um arquivo .env com a biblioteca python-dotenv:
pip install python-dotenv
Crie o arquivo /home/deploy/myapp/.env:
SECRET_KEY=sua-chave-secreta-aqui
DATABASE_URL=postgresql://usuario:senha@localhost/banco
DEBUG=False
No settings.py ou app.py:
from dotenv import load_dotenv
import os
load_dotenv()
SECRET_KEY = os.getenv('SECRET_KEY')
Adicione o .env ao .gitignore para garantir que ele nunca entre no repositório.
Banco de Dados em Produção
SQLite funciona para desenvolvimento, mas não para produção com múltiplos workers. Use PostgreSQL:
sudo apt install postgresql postgresql-contrib
sudo -u postgres createuser --interactive
sudo -u postgres createdb meubancodados
pip install psycopg2-binary
Configure a DATABASE_URL no seu .env e atualize as configurações do Django ou Flask-SQLAlchemy conforme necessário.
Monitoramento e Logs
Acompanhe os logs do Gunicorn via systemd:
sudo journalctl -u myapp -f
Os logs do Nginx ficam em:
/var/log/nginx/access.log
/var/log/nginx/error.log
Para aplicações com mais tráfego, vale integrar uma ferramenta como o Sentry, que captura exceções Python em tempo real e envia alertas antes que o cliente perceba o problema.
Escolhendo o VPS Certo para Aplicações Python
A performance de uma aplicação Python em produção depende diretamente do hardware. Latência de disco afeta o banco de dados. Latência de rede afeta o usuário final.
Para desenvolvedores e agências brasileiras, um VPS com NVMe em datacenter no Brasil reduz a latência de forma consistente para quem acessa de dentro do país. A Napoleon oferece VPS com NVMe em datacenters no Brasil e nos EUA, com suporte 24/7 via WhatsApp e Telegram — o que facilita resolver incidentes sem ficar esperando resposta de ticket.
O acesso root completo necessário para configurar Gunicorn, systemd, Nginx e PostgreSQL conforme este guia está disponível em qualquer plano VPS, sem restrições de painel proprietário.
FAQs
Posso hospedar Flask e Django no mesmo VPS?
Sim. Cada aplicação usa um socket Unix diferente e um bloco de servidor separado no Nginx. Você pode rodar quantas aplicações o hardware suportar, cada uma com seu próprio serviço systemd e ambiente virtual Python.
Qual a diferença entre usar porta TCP e socket Unix no Gunicorn?
Socket Unix é mais rápido porque evita a pilha de rede TCP/IP. Como Nginx e Gunicorn rodam no mesmo servidor, o socket Unix é a opção preferida para produção.
Preciso de um VPS dedicado para cada projeto de cliente?
Não necessariamente. Um VPS com recursos adequados pode hospedar múltiplos projetos Python ao mesmo tempo, cada um isolado em seu próprio usuário, ambiente virtual e serviço systemd. Para a maioria dos cenários de agência, essa separação é suficiente.
Como atualizo minha aplicação sem downtime?
Faça o pull das alterações, instale dependências novas se houver, e reinicie o serviço com sudo systemctl restart myapp. O Nginx continua servindo requisições durante o restart do Gunicorn, que normalmente leva menos de dois segundos. Para zero downtime real, use gunicorn --reload ou um processo de deploy com recarga gradual de workers.
O que fazer se o Gunicorn não iniciar após o reboot?
Verifique o status com sudo systemctl status myapp e os logs com sudo journalctl -u myapp. As causas mais comuns são caminho incorreto para o ambiente virtual no arquivo .service, permissões erradas, ou variáveis de ambiente não carregadas. Confirme que o ExecStart aponta para o binário dentro do venv.
Devo usar Nginx mesmo em um VPS pequeno?
Sim. O Nginx serve arquivos estáticos com eficiência muito maior do que o Gunicorn e atua como buffer para conexões lentas, protegendo os workers Python de ficarem presos em clientes lentos. O custo de memória é baixo e o benefício é imediato.
Como configurar HTTPS sem um domínio próprio para testes?
Use um certificado autoassinado para testes internos. Para produção, um domínio próprio é necessário para obter um certificado Let's Encrypt válido. O Certbot automatiza todo o processo de emissão e renovação.
Seguindo este guia, sua aplicação Flask ou Django estará em produção com uma stack sólida: Gunicorn gerenciando os workers Python, Nginx tratando o tráfego HTTP/HTTPS e systemd garantindo que tudo reinicia automaticamente. O próximo passo natural é monitoramento de erros, backups do banco de dados e um pipeline de deploy automatizado.



