├── README.md ├── appname ├── __init__.py ├── admin.py ├── apps.py ├── models.py ├── templates │ └── appname │ │ └── home.html ├── tests.py ├── urls.py └── views.py ├── manage.py ├── myproject ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py ├── requirements.txt ├── static └── css │ └── main.css └── templates └── base.html /README.md: -------------------------------------------------------------------------------- 1 | ## Django Frameworkida qilingan loyihamizni Debian/Ubuntu 20.04 serveriga joylash, Postgres, Nginx, Gunicorn paketlarini sozlash va ishga tushurish 2 | 3 | ESLATMA: 4 | - Loyiha nomi `project_name` 5 | - Ma'lumotlar bazasining nomi `database_name` 6 | - Ma'lumotlar bazasining foydalanuvchisining ismi `user_name` 7 | - Ma'lumotlar bazasining paroli `password` 8 | - Ubuntu foydalanuvchi nomi `sammy` 9 | Ushbu o'zgaruvchilar orniga uzingizni ma'lumotlaringizni kiriting!!! 10 | ``` 11 | **Ushbu qollanmada men quyidagi loyihadan foydalanaman, sizning loyihangizni tuzilishi menikidan farq qilishi mumkin** 12 | ├── projectname 13 | ├── appname 14 | │ ├── __init__.py 15 | │ ├── admin.py 16 | │ ├── apps.py 17 | │ ├── models.py 18 | │ ├── views.py 19 | │ └── urls.py 20 | ├── projectname 21 | │ ├── __init__.py 22 | │ ├── settings.py 23 | │ ├── urls.py 24 | │ └── wsgi.py 25 | ├── templates 26 | ├── static 27 | ├── media 28 | ├── manage.py 29 | └── requirements.txt 30 | 31 | ``` 32 | Ushbu qollanmani root foydalanuvchi sifatida bajarish tavsiya etilmaydi, Foydalanuvchi [yaratish va unga sudo huquqini](https://www.digitalocean.com/community/tutorials/how-to-create-a-new-sudo-enabled-user-on-ubuntu-20-04-quickstart) berish. 33 | ### Kerakli paketlarni o'rnatish 34 | ```sh 35 | $ sudo apt update 36 | $ sudo apt install -y python-pip python-dev libpq-dev vim git htop postgresql postgresql-contrib nginx redis-server 37 | ``` 38 | ### PostgreSQL ni sozlash 39 | Oldin ma'lumotlar bazasini va shu ma'lumotlar bazasidan foydalanuvchi yaratib olamiz. 40 | 41 | PostgreSQL ma'lumotlar bazasini o'rnatgandan so'ng PostgreSQL ma'lumotlar bazasi postgresql nomli foydalanuvchi yaratadi, biz ma'lumotlar bazasini sozlashda o'sha foydalanuvchidan foydalanamiz, biz `sudo` komandasi `-u` parametri bilan foydalanuvchi nomini kiritishimiz kerak 42 | ``` 43 | $ sudo -u postgres psql 44 | ``` 45 | Ma'lumotlar bazasini yaratib olamiz. 46 | ``` 47 | postgres=# CREATE DATABASE database_name; 48 | ``` 49 | Yaratilgan ma'lumotlar bazasidan foydalanuvchi yaratamiz. 50 | ```sh 51 | postgres=# CREATE USER user_name WITH PASSWORD 'password'; 52 | ``` 53 | Ma'lumotlar bazasini sozlab olamiz 54 | - Kodirofkani utf8 ga o'zgartiramiz 55 | - Tranzaktsiyalarni kutilmagan ma'lumotlar bazasi foydalanuvchisidan cheklab qoyamiz 56 | - Timezone ni UTC ga o'zgartirish (agarda siz loyihangizni boshqa UTC ishlatsangiz shunga o'zgartirish tavsfiya etiladi) 57 | ```sh 58 | postgres=# ALTER ROLE user_name SET client_encoding TO 'utf8'; 59 | postgres=# ALTER ROLE user_name SET default_transaction_isolation TO 'read committed'; 60 | postgres=# ALTER ROLE user_name SET timezone TO 'UTC'; 61 | ``` 62 | Foydalanuvchiga ma'lumotlar bazasini boshqarishga huquq berish 63 | ```sh 64 | postgres=# GRANT ALL PRIVILEGES ON DATABASE user_name TO database_name; 65 | ``` 66 | Endi PostgreSQL dan chiqamiz. 67 | ```sh 68 | postgres=# \q 69 | ``` 70 | ### Loyihani git repositoriyasidan yuklab olish 71 | ```sh 72 | $ git clone your_repository_link 73 | ``` 74 | ### Virtual muhit 75 | Birinchi navbatda [Virtual muhitni](https://docs.python.org/3/library/venv.html) yaratib olamiz. 76 | ```sh 77 | $ cd my_project 78 | $ python3 -m venv venv 79 | ``` 80 | Virtual muhitni aktivatsiya qilish va kerakli kutubxonalarni o'rnatish 81 | ```sh 82 | $ . venv/bin/activate && pip3 insatll -r requirements.txt 83 | ``` 84 | Agarda siz loyihangizda boshqa qo'shimcha kutubxonalarni ishlatgan bolsangiz requirements.txt ga qo'shib qo'yishingiz kerak bo'ladi 85 | ### Loyihani sozlash 86 | Loyihamizni serverda ishga tushurish uchun oldin loyihani sozlab olishimiz kerak, loyiha sozlamari `settings.py` faylida joylashishi bilsangiz kerak? xa albatta bilasiz degan ummida man, `ALLOWED_HOSTS` ro'yhatimizda loyihani ishga tushirilgan server IP va domen nomlarini kiritishimiz kerak bu Django loyihamiz qaysi serverdan kelgan xabarlarga javob qaytarishi bilishi uchun kerak bo'ladi. 87 | ```python 88 | ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP'] 89 | ``` 90 | Ma'lumotlar bazasini sozlamarini saqlaydigan dictga o'zgartirish kirishimiz kerak, ya'ni qaysi ma'lumotlar bazasiga ulanish, ma'lumotlar bazasini foydalanuvchising ismi va paroli, ma'lumotlar bazasimiz qaysi port da ishlab turganini kiritishimiz kerak 91 | ```python 92 | DATABASES = { 93 | 'default': { 94 | 'ENGINE': 'django.db.backends.postgresql_psycopg2', 95 | 'NAME': 'database_name', 96 | 'USER': 'user_name', 97 | 'PASSWORD': 'password', 98 | 'HOST': 'localhost', 99 | 'PORT': '', 100 | } 101 | } 102 | ``` 103 | Statik fayllarni qaerga jo'ylashtirish keraklini bildiradigan o'zgaruvchi yaratishimiz kerak, django loyihamizni localhost da ishlatganimizda bu o'zgaruvchi kerak bolmaydi chunki `DEBUG=True` holatda statik fayllarni django qayta ishlaydi `DEBUG=False` xolatda esa statik fayllarni Nginx(proxy-server) qayta ishlaydi. 104 | settings.py faylni oxiriga `STATIC_ROOT` o'zgaruvchi elon qilamiz va `BASE_DIR` (loyihamiz joylashgan joy) ga statik fayllarni saqlash uchun mo'ljallangan `staticfiles` nomli directoriyani qo'shib qoyamiz 105 | ```python 106 | STATIC_ROOT = BASE_DIR / 'staticfiles' 107 | ``` 108 | Migratsiyalarni yaratib ularni ma'lumotlar bazamizga saqlaymiz, `python3 manage.py makemigrations` komandasi modelimizni holatini migratsiya faylida saqlab qoyadi va `python3 manage.py migrate` komandasi esa migratsiya fayllarini ma'lumotlar bazamizga saqlaydi 109 | ```sh 110 | (venv)$ python3 manage.py makemigrations 111 | (venv)$ python3 manage.py migrate 112 | ``` 113 | Endilikda admin paneliga kira olishimiz uchun superuser yaratib olamiz. 114 | ```sh 115 | (venv)$ python3 manage.py createsuperuser 116 | ``` 117 | Nginxga statik fayllarni qaysi direktoriya(papkada) dan izlash keraklikini ko'rsatishimiz uchun statik fayllarni bir joyga jamlab olamiz. 118 | ```sh 119 | (venv)$ python3 manage.py collectstatic 120 | ``` 121 | Va nihoyat biz loyihamizni tog'ri sozlaganimizni bilishimiz uchun loyihani ishga tushirib ko'rishimiz mumkin 122 | ```sh 123 | python3 manage.py runserver 0.0.0.0:8000 124 | ``` 125 | Brauzeringizda server ipisiga 8000-portni qo'shib yozib tekshirib ko'rishingiz mumkin 126 | example: server_ip:8000 127 | Tushunarliki bunday qilib loyihani ishlatib qoyib bolmaydi chunki loyihamizni real serverga joylaganimizda `DEBUG=FALSE` bo'lishi kerak bu foydalanuvchiga loyihamizda yuz bergan xatoliklarni ko'rsatmaslikimiz uchun kerak. 128 | Virtual muhitni deaktivatsiya qilishimizdan oldin gunicorn kelgan habarlga javob qayta olishini tekshirib ko'rishimiz kerak, biz loyihamiz katalogiga kirib, `gunicorn` yordamida loyihaning WSGI modulini yuklashga urinib ko'ramiz: 129 | ```sh 130 | cd ~/myproject 131 | gunicorn --bind 0.0.0.0:8000 myproject.wsgi 132 | ``` 133 | Bu komanda orqali Gunicorn orqali Django loyihamizni ishga tushiramiz.Orqaga qaytib loyihamiz ko'rsatilgan ip orqali ishlayotganini qayta sinab ko'rishingiz mumkin. CTRL+C tugmachasini bosib gunicorn ni toxtatib virtual muhitni deaktivatsiya qilamiz. 134 | ```sh 135 | (venv)$ deactivate 136 | ``` 137 | ### Gunicorn ni sozlash 138 | Django Loyihamizni serverda ishlatib qoyishimiz uchun [Nginx](https://nginx.org/ru/) va [Gunicorn](https://gunicorn.org/) dan foydalanamiz 139 | Gunicorn uchun systemd ni sozlab olishimiz kerak, systemd Linux xizmatlarini ishga tushurish/boshqarish uchun qulay tizim hisoblanadi. 140 | ``` 141 | $ sudo nano /etc/systemd/system/gunicorn.service 142 | ``` 143 | Yuqoridaki komanda orqali `/etc/systemd/system/` katoligida gunicorn.service faylini yaratamiz, va quyidaki sozlamarni kiritib `ctrl+x+y+y+ENTER` tugmachasini bosamiz. 144 | ```commandline 145 | [Unit] 146 | Description=gunicorn daemon 147 | After=network.target 148 | 149 | [Service] 150 | User=sammy 151 | Group=www-data 152 | WorkingDirectory=/home/sammy/myproject 153 | ExecStart=/home/sammy/myproject/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/sammy/myproject/myproject.sock myproject.wsgi:application 154 | 155 | [Install] 156 | WantedBy=multi-user.target 157 | ``` 158 | - `[Unit]` bo'limida biz qanday xizmat uchun sozlamar kirityapganimizni va qachon ishga tushirilishi keraklikni kiritamiz. 159 | - `[Service]` bo'limida foydalanuvchi nomini va qaysi guruhga mansub ekanligini kiritamiz, nginx va gunicorn muloqat qila olishi uchun foydalanuvchi guruhi sifatida `www-data` ni kiritamiz. `WorkingDirectory` da qaysi direktoriyada ishlashni bildirishimiz uchun kerak bo'ladi, `ExecStart` esa qaysi komanda orqali ishga tushirimiz keraklikini kiritamiz. 160 | - `[Install]` bo'limi nimaga keraklikini uzim ham bilmaymiz ammo buni yozmasak ishlamaydida)) 161 | Endi systemctl komandasi orqali yuqorida yozgan xizmatimizni ishga tushiramiz va OS qayta ishga tushgan paytida avtomatik tarzda ishga tushirilishi keraklikini aytamiz. 162 | ```sh 163 | $ sudo systemctl start gunicorn 164 | $ sudo systemctl enable gunicorn 165 | ``` 166 | Endi Gunicorn ni holatini tekshirib ko'ramiz 167 | ```sh 168 | $ sudo systemctl status gunicorn 169 | ``` 170 | Qollanmani davom ettirishdan oldin gunicorn holati aktiv ekanligiga ishonch hosil qiling!!! 171 | Agarda siz biron bir sabablarga ko'ra gunicorn loglarini ko'rmoqchi bolsangiz quyidaki komanda orqali buni amalga oshirishingiz mumkin 172 | ```sh 173 | $ sudo journalctl -u gunicorn 174 | ``` 175 | `gunicorn.service` fayliga o'zgarish kiritsangiz gunicorn daemoni va gunicorn xizmatini qayta ishga tushurishingiz kerak boladi 176 | ```sh 177 | $ sudo systemctl daemon-reload 178 | $ sudo systemctl restart gunicorn 179 | ``` 180 | Agarda Gunicorn ishlayotgan bo'lsa loyihangiz katoligida `myproject.sock` fayli paydo bo'ladi!!! 181 | ### Nginxni sozlash 182 | Loyihamiz uchun Nginx sozlamarini saqlaydigan yangi fayl yaratamiz. 183 | ```sh 184 | $ sudo nano /etc/nginx/sites-available/myproject 185 | ``` 186 | Va quyidaki sozlamarni nusxasini ko'chirib olamiz 187 | ```editorconfig 188 | server { 189 | server_name server_domain_or_IP; 190 | 191 | location = /favicon.ico { access_log off; log_not_found off; } 192 | location /static/ { 193 | alias /home/sammy/myproject/staticfiles/; 194 | } 195 | location /media/ { 196 | alias /home/sammy/myproject/media/; 197 | } 198 | location / { 199 | include proxy_params; 200 | proxy_pass http://unix:/home/sammy/myproject/myproject.sock; 201 | } 202 | } 203 | ``` 204 | Endi biz yuqoridaki sozlamarni saytlar katalogiga bog'lab uni faollashtiramiz: 205 | ```sh 206 | $ sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled 207 | ``` 208 | Nginx sozlamalarini kiritishda sintaksis xatolik qilmaganimizni quyidaki komanda orqali tekshirishimiz mumkin. 209 | ```sh 210 | $ sudo nginx -t 211 | ``` 212 | Agar xatoliklar yo'q bolsa Nginx qayta ishga tushuring. 213 | ```sh 214 | $ sudo systemctl restart nginx 215 | ``` 216 | Va nihoyat serverni sozlab boldik!!! Siz brauzeringizda server IP si yo'ki domenini kiritib buni tekshirib ko'rishingiz mumkin, ha aytkancha serveringiz uchun [SSL sertifikat olish](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04)ni unitmang 217 | -------------------------------------------------------------------------------- /appname/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sayfullaev1999/deployment_django_project/4df5a82832474416c41914dcdf13d10d7b469968/appname/__init__.py -------------------------------------------------------------------------------- /appname/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /appname/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class AppnameConfig(AppConfig): 5 | name = 'appname' 6 | -------------------------------------------------------------------------------- /appname/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /appname/templates/appname/home.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | {% load static %} 3 | 4 | {% block title %} 5 | Home page 6 | {% endblock %} 7 | 8 | 9 | {% block content %} 10 |