Skip to content
VDS · Situs web dan server web

Aplikasi Python: gunicorn dan systemd

Menjalankan Django, Flask, atau FastAPI di VDS: virtual environment, gunicorn dengan socket, layanan systemd, dan memilih jumlah worker untuk tier Anda.

Diperbarui 23 Agustus 2026

Server pengembangan bawaan (manage.py runserver, flask run) tidak dirancang untuk beban produksi. Di VPS, Anda memasang gunicorn atau uvicorn, lalu sebuah web server melayaninya secara eksternal.

Lingkungan

Jangan pernah memasang paket proyek ke Python sistem — pembaruan sistem akan merusak aplikasi.

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

Untuk FastAPI, pasang juga uvicorn[standard] — gunicorn menjalankannya sebagai 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

Untuk FastAPI, ganti baris peluncuran dengan --worker-class uvicorn.workers.UvicornWorker app.main:app.

systemctl daemon-reload
systemctl enable --now myapp
journalctl -u myapp -f

RuntimeDirectory=myapp membuat /run/myapp dengan izin yang diperlukan pada setiap start — jika tidak, tidak ada tempat untuk menaruh socket.

Berapa banyak worker

Rumus yang biasa dipakai adalah 2 × cores + 1, tetapi ini terbentur batas memori: setiap worker Django memakai 80–200 MB.

TierCoreWorker
VDS-112
VDS-223
VDS-345
VDS-469

Jika aplikasi banyak menghabiskan waktu menunggu jaringan dan database, tambahkan --threads 2 alih-alih menambah jumlah proses.

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/; }

Layani file statis Django langsung dengan Nginx setelah mengumpulkannya: collectstatic. Melewatkannya melalui Python hanya menambah beban yang tidak perlu.

Kesalahan umum

GejalaPenyebab
502 dan connect() to unix:... failed (13)Nginx tidak punya izin untuk socket — atur --umask 007 dan grup bersama
ModuleNotFoundErrorDijalankan dengan Python sistem, bukan dari venv
DisallowedHost di DjangoDomain belum ditambahkan ke ALLOWED_HOSTS
Worker dimatikan karena timeoutRequest berjalan lama — naikkan --timeout, pindahkan pekerjaan berat ke queue
Semuanya berhenti setelah rilisAnda lupa systemctl restart myapp — kode di memori tidak memperbarui dirinya sendiri

Simpan rahasia di EnvironmentFile dengan izin 600, bukan di settings.py. File settings cepat atau lambat akan berakhir di repositori.