Lewati ke isi

Server & Infrastruktur

Cara Deploy Django di VPS dengan Nginx dan PostgreSQL

Langkah deploy Django ke VPS Ubuntu 24.04 memakai PostgreSQL, Gunicorn, dan Nginx, termasuk setelan produksi, file statis, dan cek keamanan bawaan.

Terbit 5 menit baca

Jawaban singkat

Deploy Django di VPS berarti menyiapkan database PostgreSQL, memasang proyek di virtualenv, mengatur settings produksi (DEBUG mati, ALLOWED_HOSTS, STATIC_ROOT), menjalankan Gunicorn lewat systemd, lalu Nginx sebagai reverse proxy dan penyaji file statis.

Daftar isi
  1. Langkah 1: Pasang paket sistem
  2. Langkah 2: Buat database dan pengguna PostgreSQL
  3. Langkah 3: Siapkan pengguna, kode, dan virtualenv
  4. Langkah 4: Atur settings untuk produksi
  5. Langkah 5: Migrasi, file statis, dan cek keamanan
  6. Langkah 6: Jalankan Gunicorn lewat systemd
  7. Langkah 7: Konfigurasi Nginx
  8. Langkah 8: Jadwalkan backup database
  9. Komponen apa saja yang dipakai?
  10. Pertanyaan yang sering diajukan

Sudah siap memindahkan proyek Django dari runserver ke server sungguhan? Susunan yang paling umum dan teruji adalah PostgreSQL sebagai database, Gunicorn sebagai server aplikasi, dan Nginx di depan untuk HTTPS dan file statis. Semuanya muat di satu VPS untuk aplikasi kecil sampai menengah.

Panduan ini memakai Ubuntu 24.04 dengan Python 3.12 bawaan. Sebelum mulai, cek tabel kompatibilitas Python di dokumentasi Django untuk versi Django yang kamu pakai.

Langkah 1: Pasang paket sistem

sudo apt update
sudo apt install -y python3-venv python3-dev build-essential \
  postgresql postgresql-contrib nginx git

Paket postgresql di Ubuntu 24.04 memasang PostgreSQL versi 16 dari repositori resmi Ubuntu. Kalau butuh versi lebih baru, PostgreSQL menyediakan repositori apt sendiri. Belum yakin PostgreSQL pilihan tepat? Baca perbandingan PostgreSQL, MySQL, dan MariaDB.

Langkah 2: Buat database dan pengguna PostgreSQL

sudo -u postgres createuser --pwprompt appdjango
sudo -u postgres createdb --owner=appdjango appdjango

Dengan --owner, pengguna appdjango menjadi pemilik database dan bisa membuat tabel di skema public. Ini penting sejak PostgreSQL 15, karena pengguna biasa tidak lagi otomatis boleh membuat objek di skema public milik database orang lain.

Biarkan PostgreSQL hanya mendengarkan localhost (bawaan Ubuntu). Aplikasi dan database di server yang sama tidak perlu port 5432 terbuka ke internet.

Langkah 3: Siapkan pengguna, kode, dan virtualenv

sudo adduser --system --group --home /srv/django django
sudo -u django git clone https://github.com/akunmu/proyekku.git /srv/django/app
sudo -u django python3 -m venv /srv/django/venv
sudo -u django /srv/django/venv/bin/pip install -r /srv/django/app/requirements.txt
sudo -u django /srv/django/venv/bin/pip install gunicorn "psycopg[binary]"

Paket psycopg (versi 3) adalah driver PostgreSQL yang didukung Django versi baru. Bila proyek lama masih memakai psycopg2, tidak masalah, keduanya bisa bekerja.

Langkah 4: Atur settings untuk produksi

Dokumentasi Django punya daftar periksa deployment resmi. Setelan paling penting:

import os

DEBUG = False
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
ALLOWED_HOSTS = ["proyekku.example"]
CSRF_TRUSTED_ORIGINS = ["https://proyekku.example"]

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "appdjango",
        "USER": "appdjango",
        "PASSWORD": os.environ["DB_PASSWORD"],
        "HOST": "localhost",
        "PORT": "5432",
    }
}

STATIC_ROOT = "/srv/django/static"
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

Simpan nilai rahasia (DJANGO_SECRET_KEY, DB_PASSWORD) di file /srv/django/.env berformat NAMA=nilai, milik pengguna django dengan izin 600, lalu muat lewat systemd di langkah 6. SECURE_PROXY_SSL_HEADER hanya aman dipakai bila Nginx memang menimpa header X-Forwarded-Proto, seperti pada konfigurasi di langkah 7.

Langkah 5: Migrasi, file statis, dan cek keamanan

Jalankan dengan variabel lingkungan yang sama seperti produksi:

cd /srv/django/app
sudo -u django bash -c 'set -a; source /srv/django/.env; set +a; \
  /srv/django/venv/bin/python manage.py migrate && \
  /srv/django/venv/bin/python manage.py collectstatic --noinput && \
  /srv/django/venv/bin/python manage.py check --deploy'

Agar collectstatic bisa menulis, buat dulu foldernya: sudo mkdir -p /srv/django/static && sudo chown django:www-data /srv/django/static. Perintah check --deploy membandingkan settings-mu dengan daftar periksa produksi dan memberi peringatan bila ada yang terlewat, misalnya HSTS belum diatur. Baca setiap peringatannya, jangan diabaikan begitu saja.

Langkah 6: Jalankan Gunicorn lewat systemd

Buat /etc/systemd/system/django.service:

[Unit]
Description=Gunicorn untuk proyekku
After=network.target postgresql.service

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

[Install]
WantedBy=multi-user.target

Ganti config.wsgi dengan nama modul proyekmu (folder yang berisi settings.py dan wsgi.py). Aktifkan:

sudo systemctl daemon-reload
sudo systemctl enable --now django
journalctl -u django -f

Pembahasan lebih rinci soal jumlah worker dan reload ada di panduan deploy Flask dengan Gunicorn, karena prinsipnya sama.

Langkah 7: Konfigurasi Nginx

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

server {
    listen 80;
    server_name proyekku.example;

    location /static/ {
        alias /srv/django/static/;
    }

    location /media/ {
        alias /srv/django/media/;
    }

    location / {
        proxy_pass http://unix:/run/django/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;
    }
}

Aktifkan dengan symlink ke sites-enabled, uji dengan sudo nginx -t, lalu reload. Setelah halaman terbuka lewat HTTP, pasang sertifikat dengan Certbot dan Let's Encrypt.

Langkah 8: Jadwalkan backup database

Data di PostgreSQL adalah aset terpenting aplikasi. Minimal, jalankan pg_dump terjadwal dan kirim hasilnya ke lokasi lain di luar server. Contoh lengkap dengan cron ada di panduan backup database MySQL dan PostgreSQL otomatis.

Komponen apa saja yang dipakai?

KomponenPeranLokasi di panduan ini
PostgreSQLMenyimpan dataLayanan postgresql, port 5432 lokal
GunicornMenjalankan kode Django/run/django/gunicorn.sock
NginxHTTPS, file statis, proxy/etc/nginx/sites-available/proyekku
systemdMenjaga Gunicorn tetap hidupdjango.service

Pertanyaan yang sering diajukan

Kenapa CSS admin Django tidak tampil setelah DEBUG dimatikan?

Saat DEBUG mati, Django tidak lagi menyajikan file statis. Pastikan collectstatic sudah dijalankan dan blok location /static/ di Nginx menunjuk ke STATIC_ROOT.

Muncul error 400 Bad Request, apa penyebabnya?

Hampir selalu karena domain belum ada di ALLOWED_HOSTS. Tambahkan domain yang dipakai pengunjung, lalu reload layanan Gunicorn.

Apa yang dijalankan setiap kali deploy versi baru?

git pull, pip install -r requirements.txt, migrate, collectstatic --noinput, lalu sudo systemctl reload django.

Perlukah Docker untuk deploy Django?

Tidak wajib. Susunan di atas berjalan langsung di VPS. Docker berguna bila kamu ingin lingkungan yang identik di laptop, staging, dan produksi.

Checklist sebelum go-live:

  • DEBUG = False, SECRET_KEY dari variabel lingkungan.
  • ALLOWED_HOSTS dan CSRF_TRUSTED_ORIGINS berisi domain yang benar.
  • check --deploy sudah dijalankan dan peringatannya ditinjau.
  • PostgreSQL tidak terbuka ke internet.
  • HTTPS aktif dan cookie diset Secure.
  • Backup database terjadwal dan pernah diuji pulihkan.

Sumber & referensi

Baca juga