Deploy FastAPI lên VPS với Gunicorn và Nginx

uvicorn main:app --reload rất tiện khi phát triển, nhưng không dành cho môi trường thật: không tự khởi động lại khi server reboot, không dùng hết nhân CPU, không có HTTPS. Đây là cách dựng cho đúng.

1. Chuẩn bị trên VPS

sudo apt update && sudo apt install -y python3-venv nginx

sudo adduser --system --group ungdung
sudo mkdir -p /var/www/api && sudo chown ungdung:ungdung /var/www/api

cd /var/www/api
python3 -m venv .venv
.venv/bin/pip install fastapi "uvicorn[standard]" gunicorn

2. Chạy thử với Gunicorn

.venv/bin/gunicorn main:app \
  -k uvicorn.workers.UvicornWorker \
  -w 4 -b 127.0.0.1:8000

Gunicorn quản lý nhiều tiến trình worker, mỗi worker chạy Uvicorn. Số worker hợp lý là 2 × số nhân CPU + 1. Chỉ lắng nghe trên 127.0.0.1 — Nginx sẽ là thứ duy nhất đứng ra ngoài.

3. Dịch vụ systemd

# /etc/systemd/system/api.service
[Unit]
Description=FastAPI app
After=network.target

[Service]
User=ungdung
WorkingDirectory=/var/www/api
EnvironmentFile=/var/www/api/.env
ExecStart=/var/www/api/.venv/bin/gunicorn main:app \
  -k uvicorn.workers.UvicornWorker -w 4 -b 127.0.0.1:8000
Restart=always

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now api
sudo systemctl status api
sudo journalctl -u api -f        # xem log

4. Nginx làm reverse proxy

# /etc/nginx/sites-available/api
server {
    listen 80;
    server_name api.example.com;

    client_max_body_size 20M;

    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;
    }
}
sudo ln -s /etc/nginx/sites-available/api /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

5. HTTPS miễn phí

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d api.example.com

Certbot tự sửa cấu hình Nginx và tự gia hạn chứng chỉ.

6. Cập nhật code

cd /var/www/api
git pull
.venv/bin/pip install -r requirements.txt
sudo systemctl restart api

Danh sách kiểm tra trước khi mở cho người dùng

  • Tắt chế độ debug, ẩn trang /docs nếu API không công khai.
  • Bật tường lửa: chỉ mở cổng 22, 80, 443.
  • Đặt secret trong .env với quyền chmod 600.
  • Có sao lưu database định kỳ và đã thử khôi phục ít nhất một lần.
Lên đầu trang