🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Como implantar Flask com Gunicorn e Nginx no Ubuntu VPS: Guia 2026 completo

⏱️6 min read  ·  1,131 words

O servidor de desenvolvimento integrado do Flask não é adequado para produção – é de thread único, não tem gerenciamento de processos e expõe tracebacks brutos do Python. Uma implantação de produção do Flask usaGunicórnio como o servidor de aplicativos WSGI eNginx como proxy reverso. Este guia cobre a configuração completa no Ubuntu 22.04.

Visão Geral da Arquitetura

Internet → Nginx (port 80/443, SSL termination, static files)
 ↓
 Gunicorn (port 8000, multiple worker processes)
 ↓
 Flask Application (WSGI app)

Etapa 1: Configuração do servidor

sudo apt update && sudo apt upgrade -y
sudo apt install -y python3-pip python3-venv nginx certbot python3-certbot-nginx

# Create application user (don't run as root)
sudo useradd -m -s /bin/bash flaskapp
sudo mkdir /var/www/myapp
sudo chown flaskapp:flaskapp /var/www/myapp

Etapa 2: Implantar aplicativo

sudo su - flaskapp
cd /var/www/myapp

# Clone your repo
git clone https://github.com/youruser/myapp.git .

# Create virtual environment
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install gunicorn

Seu ponto de entrada do aplicativo Flask (app.py or wsgi.py):

# wsgi.py
from myapp import create_app

app = create_app()

if __name__ == '__main__':
 app.run()

Etapa 3: configurar o Gunicorn

# /var/www/myapp/gunicorn.conf.py
bind = "127.0.0.1:8000"
workers = 4 # rule: (2 × CPU cores) + 1
worker_class = "gthread" # threaded worker for I/O-bound apps
threads = 2
timeout = 120
keepalive = 5
max_requests = 1000 # restart worker after N requests (prevents memory leaks)
max_requests_jitter = 50 # randomize restart to avoid thundering herd
errorlog = "/var/log/gunicorn/error.log"
accesslog = "/var/log/gunicorn/access.log"
loglevel = "info"
preload_app = True # load app before forking workers (faster startup)
sudo mkdir /var/log/gunicorn
sudo chown flaskapp:flaskapp /var/log/gunicorn

# Test gunicorn starts correctly
cd /var/www/myapp
source venv/bin/activate
gunicorn --config gunicorn.conf.py wsgi:app

Etapa 4: serviço systemd

# /etc/systemd/system/myapp.service
[Unit]
Description=Gunicorn daemon for myapp
After=network.target

[Service]
User=flaskapp
Group=flaskapp
WorkingDirectory=/var/www/myapp
Environment="PATH=/var/www/myapp/venv/bin"
EnvironmentFile=/var/www/myapp/.env
ExecStart=/var/www/myapp/venv/bin/gunicorn --config gunicorn.conf.py wsgi:app
ExecReload=/bin/kill -s HUP $MAINPID
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp # start on boot
sudo systemctl status myapp # verify running

Etapa 5: configuração do Nginx

# /etc/nginx/sites-available/myapp
server {
 listen 80;
 server_name yourdomain.com www.yourdomain.com;

 # Static files served directly by Nginx (much faster than Gunicorn)
 location /static {
 alias /var/www/myapp/static;
 expires 30d;
 add_header Cache-Control "public, immutable";
 }

 # Proxy everything else to Gunicorn
 location / {
 proxy_pass http://127.0.0.1:8000;
 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto $scheme;
 proxy_read_timeout 120s;
 proxy_connect_timeout 10s;

 # Security headers
 add_header X-Frame-Options "SAMEORIGIN";
 add_header X-Content-Type-Options "nosniff";
 add_header Referrer-Policy "strict-origin-when-cross-origin";
 }

 # Upload size limit
 client_max_body_size 16M;
}
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Etapa 6: SSL com Let’s Encrypt

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Verify auto-renewal
sudo certbot renew --dry-run

O Certbot modifica automaticamente sua configuração do Nginx para adicionar SSL, redirecionar HTTP para HTTPS e adicionar um cron job para renovação do certificado.

Etapa 7: Fluxo de trabalho de implantação

# After code changes:
cd /var/www/myapp
git pull origin main
source venv/bin/activate
pip install -r requirements.txt # if dependencies changed
flask db upgrade # if migrations exist

# Zero-downtime reload (sends SIGHUP to Gunicorn master)
sudo systemctl reload myapp

# Full restart (brief downtime)
sudo systemctl restart myapp

Variáveis de ambiente (Produção)

# /var/www/myapp/.env (permissions: 600, owned by flaskapp)
FLASK_ENV=production
SECRET_KEY=your-long-random-secret-key
DATABASE_URL=postgresql://user:pass@localhost/mydb
REDIS_URL=redis://localhost:6379/0
sudo chmod 600 /var/www/myapp/.env
sudo chown flaskapp:flaskapp /var/www/myapp/.env

Monitoramento e Logs

# View logs
sudo journalctl -u myapp -f # systemd logs
sudo tail -f /var/log/gunicorn/error.log
sudo tail -f /var/log/nginx/access.log

# Check worker processes
sudo systemctl status myapp
pgrep -a gunicorn

Perguntas frequentes

P: Quantos trabalhadores Gunicorn devo usar
A: (2 × núcleos de CPU) + 1 é a fórmula padrão.

R: Gunicorn para simplicidade e familiaridade com o ecossistema Python. uWSGI é mais rápido, mas mais complexo de configurar. Para a maioria dos aplicativos Flask, o Gunicorn funciona de forma idêntica e é muito mais simples de configurar e manter
P: Por que não apenas executar o Flask diretamente na porta 80? per connection, no SSL optimization, and slow static file serving.

Q: How do I handle zero-downtime deploys?
sends SIGHUP to Gunicorn master, which gracefully replaces workers with new ones while finishing in-flight requests. New code loads in new workers without dropping connections.

Q: Should I use Docker instead?
A: systemctl reload myappA: Docker is excellent for multi-service apps (with Docker Compose) and for consistency across environments. For a single Flask app em um VPS, systemd + Gunicorn + Nginx é mais simples, usa menos memória e é mais fácil de depurar. Ambas as abordagens funcionam bem

Conclusão
Esta configuração lida com: vários processos de trabalho para simultaneidade, tempo de inatividade zero. recarregamentos, encerramento de SSL, otimização de arquivos estáticos e reinicialização automática de processos em caso de falha. É tudo o que você precisa para atender um aplicativo Flask de produção de maneira confiável.

Esta configuração lida com: vários processos de trabalho para simultaneidade, tempo de inatividade zero. recarregamentos, encerramento de SSL, otimização de arquivos estáticos e reinicialização automática de processos em caso de falha. É tudo o que você precisa para atender um aplicativo Flask de produção de maneira confiável.

Esta configuração lida com: vários processos de trabalho para simultaneidade, tempo de inatividade zero. recarregamentos, encerramento de SSL, otimização de arquivos estáticos e reinicialização automática de processos em caso de falha. É tudo o que você precisa para atender um aplicativo Flask de produção de maneira confiável.Esta configuração lida com: vários processos de trabalho para simultaneidade, tempo de inatividade zero. recarregamentos, encerramento de SSL, otimização de arquivos estáticos e reinicialização automática de processos em caso de falha. É tudo o que você precisa para atender um aplicativo Flask de produção de maneira confiável.Esta configuração lida com: vários processos de trabalho para simultaneidade, tempo de inatividade zero. recarregamentos, encerramento de SSL, otimização de arquivos estáticos e reinicialização automática de processos em caso de falha. É tudo o que você precisa para atender um aplicativo Flask de produção de maneira confiável.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা