Mendeploy Situs Web Django Menggunakan Nginx dan Gunicorn

797

Artikel ini berisi langkah-langkah memasang / deploy aplikasi web atau situs web yang dibuat dengan framework Django di Ubuntu linux menggunakan Nginx dan Gunicorn dengan konfigurasi reverse proxy. Diadaptasi dari artikel di DigitalOcean dengan perubahan dan peringkasan.

OS yang digunakan di sini adalah Ubuntu 20.

Software yang digunakan diunduh dari apt (belum termasuk sistem basis data, jika memang diperlukan):

apt install python3-pip python3-dev nginx curl

Anggaplah proyek app webnya bernama proyek1 yang nantinya bisa diakses via URL (misalnya) proyek1.com. Gunakan akun root atau memiliki sudo.

Memasang App Sebagai Service

Untuk "memasang" app web ini di lingkungan Ubuntu, akan digunakan systemd.

Di virtual env Python Anda, install gunicorn via pip secara lokal (per user), bukan global ya..:

pip install gunicorn

Buatlah file /etc/systemd/system/gunicorn_proyek1.socket:

[Unit]
Description=gunicorn socket for proyek1.com

[Socket]
ListenStream=/run/gunicorn_proyek1.sock

[Install]
WantedBy=sockets.target

Edit dahulu file di atas.

Lalu buat satu file lagi /etc/systemd/system/gunicorn_proyek1.service:

[Unit]
Description=gunicorn daemon for proyek1.com
Requires=gunicorn_proyek1.socket
After=network.target

[Service]
User=user1
Group=www-data
WorkingDirectory=/home/user1/soaring_ego
ExecStart=/home/user1/.virtualenvs/blog/bin/gunicorn \
          --access-logfile /home/user1/log/gunicorn/access_proyek1.log \
          --error-logfile /home/user1/log/gunicorn/error_proyek1.log \
          --workers 3 \
          --bind unix:/run/gunicorn_proyek1.sock \
          proyek1.wsgi:application

[Install]
WantedBy=multi-user.target

Hati-hati, file di atas harus diedit terlebih dahulu.

User dan Group adalah user dan grup yang akan menjalankan app web ini di linux. Sesuaikan dengan sistem Anda.

Sedangkan WorkingDirectory adalah direktori tempat Anda menaruh proyek Anda (yang ada file manage.py di dalamnya -- di-generate di awal proyek dengan django-admin startproject).

Untuk ExecStart, silakan baca di laman manual gunicorn. Yang tertera di atas adalah empat parameter penting, termasuk log dan jumlah pekerja (worker). Pastikan file gunicorn /home/user1/.virtualenvs/blog/bin/gunicorn benar-benar ada.

Di direktori konfigurasi proyek Django (tempat yang sama dengan file settings.py), ada file bernama wsgi.py bukan? Gunakan itu di parameter bind, menunjuk pada variabel application di dalam file tersebut.

Jika dirasa sudah beres, jalankan ini sebagai root:

systemctl start gunicorn_proyek1.socket
systemctl enable gunicorn_proyek1.socket
systemctl daemon-reload
systemctl restart gunicorn_proyek1.socket gunicorn_proyek1.service

Jalankan kembali perintah di atas setiap selesai memodifikasi file socket dan service di atas. Jika ada error, cek log atau cek:

service gunicorn_proyek1 status

Output di shell (hanya contoh):

● gunicorn.service - gunicorn daemon
     Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
     Active: active (running) since Fri 2020-06-26 18:52:21 UTC; 2s ago
TriggeredBy: ● gunicorn.socket
   Main PID: 22914 (gunicorn)
      Tasks: 4 (limit: 1137)
     Memory: 89.1M
     CGroup: /system.slice/gunicorn.service
             ├─22914 /home/sammy/myprojectdir/myprojectenv/bin/python /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunico>
             ├─22927 /home/sammy/myprojectdir/myprojectenv/bin/python /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunico>
             ├─22928 /home/sammy/myprojectdir/myprojectenv/bin/python /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunico>
             └─22929 /home/sammy/myprojectdir/myprojectenv/bin/python /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunico>

Jun 26 18:52:21 django-tutorial systemd[1]: Started gunicorn daemon.
Jun 26 18:52:21 django-tutorial gunicorn[22914]: [2020-06-26 18:52:21 +0000] [22914] [INFO] Starting gunicorn 20.0.4
Jun 26 18:52:21 django-tutorial gunicorn[22914]: [2020-06-26 18:52:21 +0000] [22914] [INFO] Listening at: unix:/run/gunicorn.sock (22914)
Jun 26 18:52:21 django-tutorial gunicorn[22914]: [2020-06-26 18:52:21 +0000] [22914] [INFO] Using worker: sync
Jun 26 18:52:21 django-tutorial gunicorn[22927]: [2020-06-26 18:52:21 +0000] [22927] [INFO] Booting worker with pid: 22927
Jun 26 18:52:21 django-tutorial gunicorn[22928]: [2020-06-26 18:52:21 +0000] [22928] [INFO] Booting worker with pid: 22928
Jun 26 18:52:21 django-tutorial gunicorn[22929]: [2020-06-26 18:52:21 +0000] [22929] [INFO] Booting worker with pid: 22929

Nginx Sebagai Reverse Proxy ke Gunicorn

File konfigurasinya sama seperti file config nginx pada umumnya, yang berlokasi di /etc/nginx/sites-available/. Misalnya proyek1.conf:

server {
    server_name proyek1.com;
    # Favicon, Static, and Media URL
    location = /favicon.ico { access_log off; log_not_found off; }

    location /static/ {
        alias /home/user1/proyek1/static_root/;
    }

    location /media/ {
        alias /home/user1/proyek1/media_root/;
    }

    # MAIN APP
    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn_proyek1.sock;
    }
}

Edit terlebih dahulu file di atas. Ini konfig minimal ya. Belum termasuk security. Blok location /static/ dan /media/ Anda sendiri yang tentukan -- ingat setting Django pada perintah ./manage.py collectstatic dan variabel setting STATIC_ROOT dan MEDIA_ROOT; keyword alias menunjuk ke lokasi yang sama dengan yang ditunjuk dua variabel tadi.

Bagian pentingnya adalah blok berikut (disertakan di contoh kode di atas):

location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn_proyek1.sock;
    }

Ini adalah konfig reverse proxy ke gunicorn. Pastikan file sock sama dengan konfig di file socket sebelumnya.

Agar dapat dideteksi Nginx, salin file konfig nginx di atas ke dir sites-enabled milik Nginx (cukup sebagai link symbolic, ln -s):

sudo ln -s /etc/nginx/sites-available/proyek1.conf /etc/nginx/sites-enabled

Jika semua dirasa OK, cek dan jalankan sebagai root:

nginx -t

Output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

lalu jalankan:

service nginx restart

Jika menggunakan firewall semacam ufw, izinkan Nginx:

ufw allow 'Nginx Full'

Akses app web via URL. Selesai. Cek log apabila ada error.

laman hello django