Ứng dụng Python: gunicorn và systemd
Chạy Django, Flask, hoặc FastAPI trên VDS: môi trường ảo, gunicorn với socket, dịch vụ systemd, và chọn số worker theo tier của bạn.
Cập nhật 23 tháng 8, 2026
Máy chủ phát triển tích hợp sẵn (manage.py runserver, flask run) không được thiết kế để chịu tải production. Trên VPS, bạn cài gunicorn hoặc uvicorn, và một web server phục vụ chúng ra bên ngoài.
Môi trường
Đừng bao giờ cài các gói của dự án vào Python hệ thống — một bản cập nhật hệ thống sẽ làm hỏng ứng dụng.
apt install -y python3 python3-venv python3-pip
useradd -r -m -d /srv/app -s /usr/sbin/nologin appuser
sudo -u appuser python3 -m venv /srv/app/venv
sudo -u appuser /srv/app/venv/bin/pip install -r /srv/app/requirements.txt
sudo -u appuser /srv/app/venv/bin/pip install gunicorn
Với FastAPI, cài thêm uvicorn[standard] — gunicorn chạy nó như một worker class.
Service
/etc/systemd/system/myapp.service:
[Unit]
Description=Python app
After=network-online.target postgresql.service
[Service]
User=appuser
WorkingDirectory=/srv/app
EnvironmentFile=/srv/app/.env
ExecStart=/srv/app/venv/bin/gunicorn \
--workers 3 \
--bind unix:/run/myapp/gunicorn.sock \
--access-logfile - \
myproject.wsgi:application
RuntimeDirectory=myapp
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Với FastAPI, thay dòng khởi chạy bằng --worker-class uvicorn.workers.UvicornWorker app.main:app.
systemctl daemon-reload
systemctl enable --now myapp
journalctl -u myapp -f
RuntimeDirectory=myapp tạo /run/myapp với các quyền cần thiết mỗi lần khởi động — nếu không thì không có chỗ để đặt socket.
Bao nhiêu worker
Công thức thông thường là 2 × cores + 1, nhưng nó vấp phải giới hạn bộ nhớ: mỗi worker Django dùng 80–200 MB.
| Tier | Cores | Workers |
|---|---|---|
| VDS-1 | 1 | 2 |
| VDS-2 | 2 | 3 |
| VDS-3 | 4 | 5 |
| VDS-4 | 6 | 9 |
Nếu ứng dụng dành nhiều thời gian chờ mạng và cơ sở dữ liệu, hãy thêm --threads 2 thay vì tăng số tiến trình.
Web server
location / {
proxy_pass http://unix:/run/myapp/gunicorn.sock;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static/ { alias /srv/app/static/; }
Phục vụ trực tiếp các tệp tĩnh của Django bằng Nginx sau khi thu thập chúng: collectstatic. Đưa chúng qua Python sẽ tạo thêm tải không cần thiết.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân |
|---|---|
502 và connect() to unix:... failed (13) | Nginx không có quyền với socket — đặt --umask 007 và một nhóm chung |
ModuleNotFoundError | Chạy bằng Python hệ thống thay vì từ venv |
DisallowedHost trong Django | Tên miền chưa được thêm vào ALLOWED_HOSTS |
| Worker bị kill do hết thời gian chờ | Một request dài — tăng --timeout, chuyển công việc nặng sang hàng đợi |
| Mọi thứ dừng sau một bản release | Bạn quên systemctl restart myapp — mã trong bộ nhớ không tự cập nhật |
Hãy giữ các bí mật trong một
EnvironmentFilevới quyền600, không phải trongsettings.py. Tệp cài đặt rồi cũng sẽ nằm trong repository sớm muộn.