Mengkonfigurasi Debian, Nginx, dan Gunicorn untuk Proyek Django



Hari baik untuk semua

Ada tugas untuk meningkatkan server Debian di Nginx untuk proyek-proyek Django 3.x. Memecah banyak informasi di Internet, saya berhasil melakukan ini dengan menggabungkan rekomendasi dari beberapa situs yang berbeda. Jika Anda tertarik membaca cara mengatur server pertama Anda untuk proyek Django, selamat datang.

Saya akan bercerita sedikit tentang diri Anda sehingga Anda mengerti siapa saya. Saya bukan pengembang, bukan programmer, bukan administrator sistem, atau bahkan memiliki pendidikan IT. Saya seorang guru ilmu komputer. Tetapi di tempat kerja, saya harus menjelaskan kepada siswa beberapa poin yang sangat jauh dari kursus sekolah dalam ilmu komputer, dan salah satunya adalah pengembangan proyek di Django.

Pengaturan dasar


Untuk memulainya, kita sudah memiliki server dengan Debian 10 diinstal, seharusnya tidak ada masalah menginstal Debian. Saya memiliki instalasi yang bersih, tanpa pengaturan tambahan, jadi saya pergi ke server saya melalui root dan mulai menginstal beberapa komponen utama untuk saya.

apt-get update
apt-get install -y sudo htop git curl wget unzip zip gcc build-essential make
apt-get install -y tree redis-server nginx  libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python3-dev python-pil ython3-pil 
apt-get install -y python3-lxml libxslt-dev python-libxml2 python-libxslt1 python-dev gnumeric libpq-dev libxml2-dev libxslt1-dev libjpeg-dev libfreetype6-dev libcurl4-openssl-dev supervisor libgdbm-dev libnss3-dev ufw

Anda dapat menempatkan semua ini dalam satu instalasi, tetapi saya mendapat kesalahan, dan dalam urutan ini semuanya berjalan dengan baik.

Selanjutnya, buat pengguna baru dan tambahkan dia ke grup sudo sehingga dia dapat memulai proses atas nama pengguna super.

adduser username 
usermod -aG sudo username

di mana nama pengguna adalah nama pengguna yang akan Anda gunakan di masa depan.
Instal versi terbaru Python dari sumber. Pada saat penulisan, ini adalah 3.8.2 .

cd /home/username
curl -O https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tar.xz
tar -xf Python-3.8.2.tar.xz
cd Python-3.8.2

Penjelasan Tindakan
cd β€” , change directory;
curl β€” URL. ;
tar β€” .

Setelah mengunduh versi terbaru Python dan pindah ke direktori sumber, kami menjalankan:

./configure --enable-optimizations
make -j 2

Ini akan memungkinkan kita untuk mempersiapkan segala yang diperlukan untuk menginstal Python. Di sini, angka 2, ini adalah jumlah inti prosesor. Anda dapat mengetahuinya dengan perintah nproc .
Kami memulai instalasi.
make altinstall

Anda dapat memverifikasi bahwa Python telah diinstal dengan menggunakan perintah:

python3.8 -V

Ini akan menampilkan versi Python .
Setelah itu, kami memperbarui pip dan menginstal paket yang paling umum digunakan untuk Python .
python3.8 -m pip install -U pip
python3.8 -m pip install -U setuptools
python3.8 -m pip install pillow
python3.8 -m pip install virtualenv

Pengaturan Django


Kami me-restart sistem dan pergi di bawah pengguna yang Anda buat. Mari kita pergi ke direktori / var / www dan unduh proyek kita ke dalamnya, yang diunggah ke GitHub .

cd /var/www
sudo git clone LINK_TO_PROJECT

Konfigurasikan hak untuk operasi normal dengan direktori / var / www
sudo chown -R www-data:www-data /var/www
sudo usermod -aG www-data username
sudo chmod go-rwx /var/www
sudo chmod go+x /var/www
sudo chgrp -R www-data /var/www
sudo chmod -R go-rwx /var/www
sudo chmod -R g+rwx /var/www

Tampaknya kami melakukan tindakan tertentu dan kemudian membatalkannya, tetapi intinya adalah bahwa kami pertama-tama menghapus semua izin untuk semua orang dan kemudian menetapkannya untuk pengguna atau grup tertentu.

Kami pergi ke proyek kami, membuat lingkungan virtual dan menjalankannya:

cd djangoprojectname/
virtualenv env
source ./env/bin/activate

Jika semuanya diaktifkan, akan ada baris formulir: (env) nama pengguna @ server.

Kami akan mengirimkan / memperbarui paket-paket utama yang kami butuhkan untuk proyek kami.

pip install -U pip
pip install -U setuptools
pip install -U pillow

Kami menempatkan Django, Gunicorn dan adaptor untuk PostgreSQL.

pip install django gunicorn psycopg2-binary

Anda juga dapat menempatkan paket yang diperlukan untuk proyek Anda, saya menggunakan summernote untuk teks:

pip install django-summernote

Kami menyiapkan firewall, jadi kami perlu membuat pengecualian untuknya di port 8000 (kami menggunakannya secara default, jika kami berencana untuk menggunakan yang lain, kemudian tentukan):

sudo ufw allow 8000

Langkah yang diperlukan adalah untuk memeriksa kesehatan server:

python3.8 manage.py runserver 0.0.0.0:8000

Dan buka situs web Anda, DOMAIN_NAME: 8000 , untuk memastikan semuanya berfungsi! Tetapi, saat ini, kami belum banyak mengkonfigurasi, ini hanya pengaturan dasar, kita perlu mengkonfigurasi operasi normal server, menghubungkan statika, dll.
Jika situs Anda tidak memulai, maka Anda perlu mempelajari pengaturan (mungkin hak akses) dan melihat paket mana yang belum diinstal, semuanya sangat individual.

Untuk melengkapi dengan menekan tombol: CTRL + C .

Maka kami akan melanjutkan hanya jika proyek Anda telah dimulai, saya sangat menyarankan untuk tidak melanjutkan jika sesuatu tidak berhasil. Lebih baik untuk memperbaiki masalah pada tahap awal daripada merobohkan server ke root (saya dihancurkan 3 kali, dan kemudian saya mulai menulis instruksi ini, memperbaiki setiap tindakan).

Memeriksa pekerjaan Gunicorn:

gunicorn --bind 0.0.0.0:8000 MAINAPPNAME.wsgi

MAINAPPNAME adalah nama aplikasi utama yang berisi settings.py .

Jika server berfungsi, lanjutkan.

Untuk melengkapi dengan menekan tombol: C TRL + C .

Pengaturan setting.py


Ketika menggunakan server produksi, Anda perlu menonaktifkan debug dari proyek dan mengubah beberapa pengaturan, saya melakukan ini sebagai berikut di settings.py dari proyek saya.

DEBUG = False
if DEBUG:
    ALLOWED_HOSTS = ['*']
else:
    ALLOWED_HOSTS = ['HOST IP', 'DOMAIN NAIM', 'localhost']
...
STATIC_URL = '/static/'
if DEBUG:
    STATIC_DIR = os.path.join(BASE_DIR, 'static')
    STATICFILES_DIRS = [
        STATIC_DIR,
        '/var/www/static/',
    ]
else:
    STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
    STATICFILES_FINDERS = (
        'django.contrib.staticfiles.finders.FileSystemFinder',
        'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    )
MEDIA_URL = '/media/'

Di urls.py, saya mengubah pengaturan untuk statika dan media.

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Saya tidak tahu seberapa banyak ini adalah keputusan yang tepat, dan mungkin ada perubahan yang lebih benar pada file-file ini. Tetapi dalam hal ini cukup bagi saya untuk mengubah nilai DEBUG untuk beralih antara pengembangan dan publikasi.

Jalankan perintah:

python3.8 manage.py collectstatic

Untuk mengumpulkan statika dan menonaktifkan lingkungan virtual:

deactivate

Konfigurasikan Gunicorn


Mari kita buka untuk penyesuaian

sudo nano /etc/systemd/system/gunicorn.socket

Mari kita menulis beberapa pengaturan di file:

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Kami membuat bagian [Unit] untuk menggambarkan soket, di bagian [Soket] kami menentukan lokasi soket dan di bagian [Instal] kami perlu memasang soket pada waktu yang tepat.

Buka file utilitas systemd untuk mengkonfigurasi layanan:

sudo nano /etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=username
Group=www-data
WorkingDirectory=/var/www/djangoprojectname
ExecStart=/var/www/djangoprojectname/env/bin/gunicorn \
          --access-logfile - \
          --workers 5 \
          --bind unix:/run/gunicorn.sock \
          myproject.wsgi:application

[Install]
WantedBy=multi-user.target

Jangan lupa untuk menunjukkan pengguna Anda, nama proyek Anda dan lingkungan virtual Anda.

Sebagaimana dijelaskan kepada saya, pekerja dihitung sebagai jumlah inti prosesor * 2 + 1 .
Sekarang kami meluncurkan dan mengaktifkan soket Gunicorn.

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket

Dan pastikan untuk menguji bahwa semuanya berfungsi!

sudo systemctl status gunicorn.socket

Harus menampilkan informasi tentang layanan yang berjalan.

Tekan tombol Q untuk keluar (diperlukan dalam tata bahasa Inggris).

file /run/gunicorn.sock

Perintah terakhir harus menampilkan pesan tentang file.

Jika perintah sudo systemctl status gunicorn.socket pertama mengembalikan kesalahan, atau jika file kedua / run/gunicorn.sock perintah melaporkan bahwa file gunicorn.sock tidak ada dalam direktori, maka soket Gunicorn tidak dapat dibuat. Anda perlu memeriksa log soket Gunicorn dengan perintah berikut:

sudo journalctl -u gunicorn.socket

Lihat apa kesalahannya dan perbaiki.

Mari beralih ke pengujian aktivasi soket.

sudo systemctl status gunicorn

Kemungkinan besar Anda akan memiliki catatan:

Active: inactive (dead)

Sejauh ini, semuanya berjalan baik.

Buat koneksi ke soket melalui ikal.

curl --unix-socket /run/gunicorn.sock localhost


Dapat melempar Kesalahan Buruk (400).

Coba alih-alih localhost untuk menentukan IP server Anda , jika semuanya baik-baik saja, maka kemungkinan besar ini disebabkan oleh pengaturan nginx yang belum kami lakukan. Pindah saja.

Dan lagi, minta keluaran status:

sudo systemctl status gunicorn

Active: active (running)

Jika catatannya + ini masih ada banyak informasi, tetapi bukan tentang kesalahan, maka semuanya baik-baik saja.

Kalau tidak, kami melihat kesalahan dalam log

sudo journalctl -u gunicorn

Dan restart proses gunicorn

sudo systemctl daemon-reload
sudo systemctl restart gunicorn

Pengaturan NGINX


Kami akan membuat blok server baru untuk situs kami dan mengkonfigurasinya sehingga ketika mengakses situs kami di bilah alamat, server memahami dari mana dan dari mana mendapatkannya.

sudo nano /etc/nginx/sites-available/djangoprojectname

server {
    listen 80;
    server_name server_domain_or_IP;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        alias /var/www/djangoprojectname/static/;
    }

    location /media/ {
        alias /var/www/djangoprojectname/media/;
    }

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

Di bagian sever_name, Anda dapat menentukan beberapa alamat yang dipisahkan oleh spasi.

Tes untuk kesalahan sintaks:

sudo nginx -t

Jika tidak ada kesalahan, maka restart server dan berikan firewall kami hak yang diperlukan:

sudo systemctl restart nginx
sudo ufw allow 'Nginx Full'

Anda juga dapat menghapus akses ke port 8000

sudo ufw delete allow 8000

Pada titik ini, semuanya harus berfungsi, tetapi tidak berfungsi dengan baik sampai saya mengkonfigurasi https. Sayangnya, saya tidak bisa menjelaskan apa yang terhubung dengan ini, tetapi statika tidak dimuat, meskipun file media dimuat secara normal.

Penyiapan HTTPS


Kami akan menggunakan Cerbot untuk mengkonfigurasi

sudo apt-get install certbot python-certbot-nginx
sudo certbot –nginx

Dan ikuti petunjuk di layar. Jika ada kesalahan, hilangkan dan coba lagi. Misalnya, kesalahan dapat terjadi jika Anda menentukan nama domain yang tidak terkait dengan server ini.
Untuk secara otomatis memperbarui sertifikat, masukkan perintah.

sudo certbot renew --dry-run 

Sekarang kami sedang menguji situs dan semuanya akan berfungsi!

Jika statika masih belum muncul, maka coba buka beberapa file css yang menunjukkan alamat lengkap sebelumnya, jika Anda mendapatkan kesalahan 403, maka semuanya baik-baik saja, tetapi masalah hak akses harus dicoba, coba atur ulang semua pengaturan hak untuk data-www ke direktori / var / www . Jika kesalahan adalah 404, maka Anda perlu melihat ke arah pengaturan lokasi di pengaturan NGINX .

Penyiapan postgreSQL


Siapkan PostgreSQL dan impor data dari SQLite. Jika Anda tidak membutuhkannya, lewati langkah ini, atau ambil hanya pengaturan PostgreSQL.

Buat basis data dan pengguna.

sudo -u postgres psql

CREATE DATABASE dbforproject;
CREATE USER projectdbuser WITH PASSWORD 'password';

Kami akan mengikuti rekomendasi untuk proyek Django.

Kami mengatur penyandian default ke UTF-8, mengatur skema isolasi transaksi default menjadi "read berkomitmen", untuk memblokir pembacaan dari transaksi yang tidak dikonfirmasi. Atur zona waktu ke GMT (UTC).

ALTER ROLE projectdbuser SET client_encoding TO 'utf8';
ALTER ROLE projectdbuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE projectdbuser SET timezone TO 'UTC';

Setelah itu, Anda perlu memberi pengguna yang kami buat akses untuk mengelola basis data baru:

GRANT ALL PRIVILEGES ON DATABASE dbforproject TO projectdbuser;

Setelah semua perintah selesai, Anda dapat menutup dialog PostgreSQL menggunakan perintah:

\q

Sekarang konfigurasi PostgreSQL selesai, sekarang kita akan mengkonfigurasi Django untuk bekerja dengan benar dengan PostreSQL.

Pertama, salin data lama dari SQLite (jika perlu). Untuk melakukan ini, buka proyek Anda dan luncurkan lingkungan virtual:

cd /var/www/djangoprojectname
source ./env/bin/activate
cd mainappname/
python3.8 manage.py dumpdata > datadump.json

Ubah pengaturan untuk menghubungkan ke database:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'dbforproject',
        'USER': 'projectdbuser',
        'PASSWORD': 'password',
        'HOST': 'localhost',
        'PORT': '',
    }
}

Jalankan migrasi untuk database:

python3.8 manage.py migrate --run-syncdb

Setelah shell ini:

python3 manage.py shell

Dan tulis di dalamnya:

>>> from django.contrib.contenttypes.models import ContentType
>>> ContentType.objects.all().delete()
>>> quit()

Dan memuat data yang sebelumnya diunggah dari SQLite:

python3.8 manage.py loaddata datadump.json

Itu saja, semuanya dimulai dan bekerja untuk saya, tetapi dalam kasus kesalahan itu sangat individual, jadi saya sarankan untuk tidak melewatkan langkah-langkah dengan pengujian kinerja sehingga Anda dapat memahami pada tahap apa kesalahan itu terjadi.

Saat menulis, saya menggunakan:

  1. www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04-ru
  2. vexxhost.com/resources/tutorials/how-to-deploy-django-on-nginx-gunicorn-with-postgres
  3. pythonworld.ru/web/django-ubuntu1604.html

All Articles