Lewati ke isi

Server & Infrastruktur

Cara Deploy Aplikasi Python Flask dengan Gunicorn

Deploy Flask ke VPS Linux dengan Gunicorn, systemd, dan Nginx. Mulai dari virtualenv, jumlah worker, socket, sampai log dan pembaruan kode.

Terbit 5 menit baca

Jawaban singkat

Flask di produksi dijalankan dengan server WSGI seperti Gunicorn, bukan flask run. Pasang aplikasi di virtualenv, jalankan Gunicorn sebagai layanan systemd yang mendengarkan socket lokal, lalu taruh Nginx di depannya untuk HTTPS dan file statis.

Daftar isi
  1. Apa saja yang perlu disiapkan?
  2. Kenapa wajib memakai virtualenv?
  3. Berapa jumlah worker Gunicorn yang pas?
  4. Menjalankan Gunicorn sebagai layanan systemd
  5. Bagaimana menghubungkan Nginx ke Gunicorn?
  6. Memperbarui kode tanpa ribet
  7. Pertanyaan yang sering diajukan

Jawaban singkatnya: jalankan Flask lewat Gunicorn sebagai layanan systemd, lalu letakkan Nginx di depannya. Server bawaan flask run hanya untuk pengembangan, dan dokumentasi Flask sendiri menyarankan server WSGI produksi saat aplikasi dibuka ke publik.

Kenapa ini penting? Server pengembangan tidak dirancang untuk banyak pengunjung sekaligus, tidak menyalakan ulang dirinya saat crash, dan tidak dimaksudkan menghadapi trafik internet secara langsung. Gunicorn menangani proses worker, Nginx menangani koneksi lambat, HTTPS, dan file statis. Pembagian tugas ini yang membuat aplikasi kecil tetap stabil.

Apa saja yang perlu disiapkan?

Contoh di bawah memakai Ubuntu 24.04 atau Debian 12, tapi langkahnya mirip di distro lain. Kamu butuh:

  • VPS dengan akses SSH dan pengguna non-root ber-sudo.
  • Paket python3, python3-venv, python3-pip, dan nginx.
  • Kode aplikasi Flask di repositori Git, dengan requirements.txt.
  • Domain yang sudah diarahkan ke IP server (untuk HTTPS).

Pasang paket dasarnya:

sudo apt update
sudo apt install -y python3 python3-venv python3-pip nginx git

Kenapa wajib memakai virtualenv?

Di Ubuntu 24.04 dan Debian 12, Python sistem ditandai "externally managed". Perintah pip install ke Python sistem akan ditolak supaya paket OS tidak rusak. Virtualenv memecahkan ini sekaligus memisahkan dependensi tiap aplikasi.

sudo adduser --system --group --home /srv/flaskapp flaskapp
sudo -u flaskapp git clone https://github.com/akunmu/flaskapp.git /srv/flaskapp/app
cd /srv/flaskapp/app
sudo -u flaskapp python3 -m venv /srv/flaskapp/venv
sudo -u flaskapp /srv/flaskapp/venv/bin/pip install -r requirements.txt gunicorn

Uji dulu dari terminal. Bila objek Flask bernama app di file wsgi.py, jalankan:

sudo -u flaskapp /srv/flaskapp/venv/bin/gunicorn -w 2 -b 127.0.0.1:8000 'wsgi:app'

Lalu dari sesi SSH lain, coba curl -I http://127.0.0.1:8000. Kalau aplikasi memakai pola application factory, bentuknya 'namamodul:create_app()'. Hentikan dengan Ctrl+C setelah berhasil.

Berapa jumlah worker Gunicorn yang pas?

Dokumentasi Gunicorn memberi titik awal (2 x jumlah inti CPU) + 1. Rumus ini bukan aturan mati, tapi tempat mulai yang masuk akal sebelum kamu mengukur beban nyata.

vCPUWorker awalCatatan
13Pantau RAM, tiap worker memuat salinan aplikasi
25Umum untuk aplikasi kecil sampai menengah
49Pertimbangkan worker thread bila banyak I/O

Setiap worker adalah proses Python sendiri, jadi aplikasi yang memuat model atau data besar ke memori akan cepat menghabiskan RAM. Kalau aplikasimu banyak menunggu API atau database, coba worker berbasis thread (--threads 4) sebelum menambah proses.

Menjalankan Gunicorn sebagai layanan systemd

Supaya aplikasi menyala otomatis saat boot dan hidup lagi saat crash, buat /etc/systemd/system/flaskapp.service:

[Unit]
Description=Gunicorn untuk flaskapp
After=network.target

[Service]
User=flaskapp
Group=www-data
WorkingDirectory=/srv/flaskapp/app
RuntimeDirectory=flaskapp
EnvironmentFile=/srv/flaskapp/.env
ExecStart=/srv/flaskapp/venv/bin/gunicorn --workers 3 --bind unix:/run/flaskapp/gunicorn.sock --umask 007 --access-logfile - --error-logfile - wsgi:app
ExecReload=/bin/kill -s HUP $MAINPID
Restart=on-failure

[Install]
WantedBy=multi-user.target

Beberapa detail yang sering ditanyakan:

  • RuntimeDirectory=flaskapp membuat folder /run/flaskapp setiap layanan dimulai, tempat socket disimpan.
  • --umask 007 dan Group=www-data membuat socket bisa dibaca Nginx, tapi tidak oleh pengguna lain.
  • --access-logfile - mengirim log ke journal, jadi bisa dibaca dengan journalctl -u flaskapp -f.
  • Variabel rahasia seperti SECRET_KEY disimpan di file /srv/flaskapp/.env (dibaca lewat EnvironmentFile=, format NAMA=nilai, izin 600), jangan ditulis di kode.

Aktifkan dengan sudo systemctl daemon-reload lalu sudo systemctl enable --now flaskapp.

Bagaimana menghubungkan Nginx ke Gunicorn?

Buat /etc/nginx/sites-available/flaskapp:

server {
    listen 80;
    server_name flask.example;

    location /static/ {
        alias /srv/flaskapp/app/static/;
    }

    location / {
        proxy_pass http://unix:/run/flaskapp/gunicorn.sock;
        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;
    }
}

Aktifkan dengan symlink ke sites-enabled, jalankan sudo nginx -t, lalu sudo systemctl reload nginx. Nginx kini melayani file statis langsung dan meneruskan sisanya ke Gunicorn. Kalau peran Nginx di sini masih terasa abstrak, artikel apa itu reverse proxy menjelaskan konsepnya.

Karena Flask berada di belakang proxy, bungkus aplikasi dengan ProxyFix dari Werkzeug agar request.remote_addr dan skema https terbaca benar:

from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1)

Angka 1 berarti aplikasi mempercayai satu lapis proxy, yaitu Nginx di server yang sama. Jangan menaikkannya bila memang tidak ada proxy lain di depan, karena header palsu dari pengunjung bisa ikut dipercaya. Terakhir, pasang sertifikat dengan Certbot dan Let's Encrypt.

Memperbarui kode tanpa ribet

Alur pembaruan yang aman:

  1. cd /srv/flaskapp/app && sudo -u flaskapp git pull
  2. sudo -u flaskapp /srv/flaskapp/venv/bin/pip install -r requirements.txt
  3. sudo systemctl reload flaskapp

Perintah reload mengirim sinyal HUP. Gunicorn lalu menyalakan worker baru dengan kode terbaru dan mematikan worker lama secara bertahap. Kalau ada perubahan besar, misalnya versi Python atau pengaturan systemd, pakai restart.

Aplikasimu memakai Django, bukan Flask? Polanya hampir sama, dan panduannya ada di deploy Django dengan Nginx dan PostgreSQL.

Pertanyaan yang sering diajukan

Apakah Gunicorn bisa dipakai di Windows?

Tidak. Gunicorn dirancang untuk sistem mirip Unix seperti Linux. Di Windows, pilihan yang umum adalah Waitress, atau jalankan aplikasi di WSL atau server Linux.

Gunicorn atau uWSGI?

Keduanya server WSGI yang matang. Gunicorn lebih sederhana dikonfigurasi dan dokumentasi Flask menyediakan panduan untuknya, jadi cocok untuk mulai.

Apakah bisa tanpa Nginx?

Secara teknis bisa, tapi dokumentasi Gunicorn menyarankan menaruhnya di belakang proxy seperti Nginx agar koneksi klien yang lambat tidak menghabiskan worker.

Sumber & referensi

Baca juga