Skip to content
VDS · Website và máy chủ web

Ứ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.

TierCoresWorkers
VDS-112
VDS-223
VDS-345
VDS-469

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ứngNguyê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
ModuleNotFoundErrorChạy bằng Python hệ thống thay vì từ venv
DisallowedHost trong DjangoTê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 releaseBạ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 EnvironmentFile với quyền 600, không phải trong settings.py. Tệp cài đặt rồi cũng sẽ nằm trong repository sớm muộn.