WisarWisar
Dasturlash kitobi/10-QISM — DevOps39 daqiqa

10.2-bob: Nginx (reverse proxy, load balancer)

10-QISM — DevOps va Deploy · 2-mavzu


1. Kirish va motivatsiya

10.1-bobda biz bo'sh serverni xavfsiz sozlab, Node.js ilovamizni systemd xizmati sifatida ishga tushirdik — u 3000-portda ishlayapti (10.1: 2.6). Lekin bu yerda muammo bor: foydalanuvchi brauzerda http://203.0.113.5:3000 deb yozmaydi. U https://saytim.uz ga kiradi — ya'ni 80-port (HTTP) yoki 443-port (HTTPS), domen bilan, SSL bilan. Bundan tashqari, Node.js'ning o'zi statik fayllarni (rasm, CSS, JS) samarali bermaydi, SSL'ni yaxshi hal qilmaydi, va bitta jarayon barcha yukni ko'tara olmaydi. Demak, foydalanuvchi va ilovamiz o'rtasida turadigan, so'rovni qabul qilib, ilovaga uzatadigan darvozabon kerak. Bu — Nginx (o'qilishi: "engine-x").

Nginx — dunyodagi eng keng tarqalgan web server va reverse proxy (teskari proksi — ya'ni serverlar oldida turib, ularga so'rov uzatuvchi vositachi). U bilan biz: tashqi 80/443-portni ochib, ichki 3000-portga proxy qilamiz (foydalanuvchi 3000'ni ko'rmaydi ham); statik fayllarni to'g'ridan-to'g'ri (ilovaga tegmasdan) beramiz; SSL sertifikatini bitta joyda hal qilamiz (SSL termination); javoblarni siqamiz (gzip — trafik kamayadi); va yukni bir necha ilova nusxasiga taqsimlaymiz (load balancer — yuk muvozanatlovchi). Bularning hammasi — ilova kodiga umuman tegmasdan, faqat sozlama orqali.

Bu bob: Nginx nima (web server vs reverse proxy), forward vs reverse proxy farqi, arxitektura (master/worker, event-driven — nega tez), reverse proxy nima beradi (SSL, gzip, cache, statik, xavfsizlik), load balancing algoritmlari (round-robin, least_conn, ip_hash), config strukturasi (http/server/location bloklari, context), location matching (=, ^~, ~, prefix — prioritet), proxy_pass va header'lar (X-Forwarded-For, Host), gzip, statik fayl va cache, rate limiting (limit_req), Nginx vs Apache, SSL/TLS chuqurroq (versiya, cipher, HSTS), proxy_buffering va keepalive, proxy_cache, logging (access/error), va rewrite/return (URL qayta yozish). Bu bob 10.1 (server) ustiga quriladi va keyingi boblar (Docker — 10.3, SSL/Certbot — 10.7) uchun poydevor.

O'xshatish: Nginx — katta ofis binosining resepsiyasi va qorovuli. Tashqaridan kelgan har bir mehmon (so'rov) to'g'ridan-to'g'ri xodimning xonasiga (ilova, 3000-port) bostirib kira olmaydi — avval resepsiyaga (80/443) keladi. Resepsiya: mehmonni to'g'ri xonaga yo'naltiradi (reverse proxy — proxy_pass), shaxsini tekshiradi va kim kelganini xodimga aytadi (X-Forwarded-For header), ko'p so'raladigan bukletlarni o'zi beradi (statik fayl — xodimni bezovta qilmaydi), kirish eshigida metall detektor o'rnatadi (SSL/HTTPS, rate limiting), va agar bir nechta bir xil xona bo'lsa — navbatni teng taqsimlaydi (load balancer). Xodim (Node.js) faqat o'z ishini qiladi; mehmonlar oqimi, xavfsizlik, navbat — resepsiyaning vazifasi. Ofis qancha katta bo'lsa, resepsiyaning ahamiyati shuncha katta.

Nega muhim?

  • Har production deploy — Node/Python/PHP ilovasi deyarli doim Nginx ortida turadi (standart amaliyot).
  • Xavfsizlik va SSL — ilovani to'g'ridan internetga ochmaydi; HTTPS'ni bir joyda hal qiladi 10.7-bob.
  • Tezlik — statik fayl, gzip, cache — ilovaga yukni kamaytiradi (yuzlab-ming so'rov/sekund).
  • Masshtab — load balancing bilan bir necha nusxaga yuk taqsimlanadi (9.9: 2.x — gorizontal masshtab).

2. Nazariya — chuqur tushuntirish

2.1. Nginx nima: web server va reverse proxy

text
  NGINX — ikki rolda ishlay oladi (ko'pincha ikkalasini birga):

  1) WEB SERVER (statik server):
     Brauzer  Nginx  diskdagi fayl (index.html, style.css, logo.png)
      fayllarni TO'G'RIDAN qaytaradi (ilova kerak emas)

  2) REVERSE PROXY (teskari proksi — vositachi):
     Brauzer  Nginx  ichki ilova (Node 3000, Python 8000)  javob
      so'rovni ORQADAGI ilovaga uzatadi, javobni qaytaradi

  ODATDAGI PRODUCTION (ikkalasi birga):
  ┌─────────┐    80/443   ┌────────┐   statik fayl  diskdan
  │ Brauzer │ ────────── │ Nginx  │   /api/*  Node 3000'ga proxy
  └─────────┘             └────────┘   SSL, gzip, cache — shu yerda

   Nginx — C tilida yozilgan, juda tez, kam RAM yeydi (statikda ayniqsa)

Nginx ("engine-x") — yuqori unumdor web server va reverse proxy. Ikki asosiy rolda ishlaydi: (1) web server — diskdagi statik fayllarni (HTML, CSS, JS, rasm) to'g'ridan-to'g'ri qaytaradi (ilova ishtirokisiz); (2) reverse proxy — so'rovni orqadagi ilovaga (Node 3000, Python/uWSGI 8000) uzatib, javobni qaytaradigan vositachi. Production'da odatda ikkalasi birga ishlaydi: Nginx 80/443-portda tinglaydi, statik fayllarni o'zi beradi, /api/* kabi dinamik so'rovlarni ichki ilovaga proxy qiladi, va SSL/gzip/cache'ni shu joyda hal qiladi. Nginx C tilida yozilgan, juda tez va kam resurs yeydi — shuning uchun dunyo web-saytlarining katta qismi (Netflix, GitHub, ko'plab CDN) uni ishlatadi. Sizning NestJS ilovang ham (8-QISM) Nginx ortida turadi.

2.2. Forward proxy vs reverse proxy

text
  PROXY — ikki taraf o'rtasidagi VOSITACHI. Lekin KIM tomonida turishiga qarab 2 xil:

  FORWARD PROXY (oddiy proxy — MIJOZ tomonida):
  ┌────────┐   ┌─────────┐   ┌──────────────┐
  │ Mijoz  │  │ Proxy   │  │  Internet    │   (VPN, korxona filtri)
  └────────┘   └─────────┘   │ (har qanday) │
   Mijozni yashiradi; mijoz "qaysi saytga" borishni biladi
   Misol: VPN, korporativ filtr, maxfiylik

  REVERSE PROXY (teskari proxy — SERVER tomonida):
  ┌────────┐   ┌─────────┐   ┌──────────────┐
  │ Mijoz  │  │ Nginx   │  │ Ichki ilova  │   (Node, DB, mikroservis)
  └────────┘   └─────────┘   │  (3000, ...) │
   Serverni yashiradi; mijoz ichki tuzilmani BILMAYDI
   Misol: Nginx, API Gateway 9.8-bob, load balancer

   Forward = mijozni himoyalaydi; Reverse = serverni himoyalaydi (bizga shu kerak)

Proxy — ikki taraf o'rtasidagi vositachi. Qaysi tomonda turishiga qarab ikki xil: Forward proxy (oddiy proxy) — mijoz tomonida turadi, mijozni yashiradi (VPN, korxona internet filtri — mijoz "men qaysi saytga boraman" deb biladi, server kim kelganini bilmaydi). Reverse proxy (teskari proxy) — server tomonida turadi, serverni va ichki tuzilmani yashiradi (mijoz faqat Nginx'ni ko'radi, orqada Node 3000 yoki 10 ta mikroservis borligini bilmaydi). Bizga kerak bo'lgani — reverse proxy: u serverlarni himoyalaydi, yukni taqsimlaydi, SSL'ni hal qiladi. "Reverse" so'zi — yo'nalish teskari: oddiy proxy mijozning so'rovini tashqariga chiqaradi, reverse proxy tashqi so'rovni ichkariga kiritadi. API Gateway 9.8-bob — reverse proxy'ning ilg'or shakli.

2.3. Arxitektura: master/worker va event-driven (nega tez)

text
  NGINX JARAYON MODELI (process model):

  ┌─────────────────────────────────────────────┐
  │  MASTER PROCESS (root, 1 ta)                 │
  │  - configni o'qiydi, port'larni ochadi       │
  │  - worker'larni boshqaradi (yiqilsa qayta)   │
  └──────────────┬──────────────────────────────┘
                 │ ishni tarqatadi
       ┌─────────┼─────────┐
   ┌───▼──┐  ┌───▼──┐  ┌───▼──┐
   │worker│  │worker│  │worker│    har CPU yadrosi uchun bittadan
   │  1   │  │  2   │  │  3   │    har biri MINGLAB ulanishni boshqaradi
   └──────┘  └──────┘  └──────┘

  EVENT-DRIVEN (asinxron, non-blocking — Node event loop'iga o'xshash — 5.1):
  - Har ulanish uchun ALOHIDA thread/process EMAS (Apache eski modeli shunaqa)
  - Bitta worker — event loop bilan minglab ulanishni navbatma-navbat
  - I/O kutganda bloklanmaydi (boshqa ulanishga o'tadi)

   Shuning uchun Nginx kam RAM bilan o'n minglab parallel ulanish ko'taradi

Nginx arxitekturasimaster/worker modeli. Bitta master process (root huquqi bilan) config'ni o'qiydi, portlarni ochadi va worker process'larni boshqaradi (biri yiqilsa — qayta ishga tushiradi). Asl ishni worker'lar bajaradi — odatda har CPU yadrosi uchun bitta (worker_processes auto;). Eng muhimi — har worker event-driven (hodisaga asoslangan, asinxron, non-blocking) ishlaydi: har ulanish uchun alohida thread ochmaydi (eski Apache modeli shunaqa edi — minglab ulanishda RAM tugaydi), balki bitta worker event loop bilan minglab ulanishni navbatma-navbat boshqaradi (Node.js event loop'iga juda o'xshash — 5.1: 2.x). I/O (disk, tarmoq) kutilganda worker bloklanmaydi — boshqa ulanishga o'tadi. Natijada Nginx kam RAM bilan o'n minglab parallel ulanishni ko'taradi — bu uning asosiy ustunligi.

2.4. Reverse proxy nima beradi (afzalliklari)

text
  NGINX'NI ILOVA OLDIGA QO'YISH — nima beradi:

  1) SSL TERMINATION — HTTPS'ni Nginx hal qiladi (ilova oddiy HTTP'da)
     Brauzer ──HTTPS── Nginx ──HTTP── Node (ichki, shifrlash kerak emas)
      sertifikat bir joyda (Certbot — 10.7); ilova soddalashadi

  2) STATIK FAYL — rasm/CSS/JS'ni Nginx beradi (Node band bo'lmaydi)
      Node faqat dinamik /api uchun; statik 10x tezroq

  3) GZIP/SIQISH — javobni siqib yuboradi (trafik 70%+ kamayadi)

  4) CACHING — javoblarni vaqtincha saqlaydi (ilova qayta hisoblamaydi)

  5) LOAD BALANCING — yukni bir necha nusxaga taqsimlaydi 2.5-bob

  6) XAVFSIZLIK — ilova porti (3000) tashqaridan YOPIQ; rate limit; header yashirish
      faqat 80/443 ochiq (10.1: 2.7); 3000 lokalda qoladi

   Bularning hammasi ILOVA KODIGA tegmasdan — faqat Nginx sozlamasi

Reverse proxy (Nginx) ilova oldiga qo'yilganda nima beradi: (1) SSL termination — HTTPS'ni Nginx hal qiladi, ilovaga oddiy HTTP'da uzatadi (sertifikat bitta joyda — Certbot bilan, 10.7; ilova shifrlash bilan bosh qotirmaydi); (2) statik fayl — rasm/CSS/JS'ni Nginx to'g'ridan beradi (Node band bo'lmaydi, ~10x tez); (3) gzip/siqish — javobni siqib, trafikni keskin kamaytiradi; (4) caching — javoblarni vaqtincha saqlab, ilovani qayta-qayta ishlatmaydi; (5) load balancing — yukni nusxalarga taqsimlaydi 2.5-bob; (6) xavfsizlik — ilova porti (3000) tashqaridan yopiq qoladi (faqat 80/443 ochiq — 10.1: 2.7), rate limiting, server header'larini yashirish. Bularning barchasi ilova kodiga umuman tegmasdan — faqat Nginx config'i orqali amalga oshadi. Shuning uchun Nginx — production'ning ajralmas qismi.

2.5. Load balancing algoritmlari (round-robin, least_conn, ip_hash)

text
  LOAD BALANCER — yukni bir necha ilova nusxasiga TAQSIMLAYDI:

  ┌────────┐       ┌────────┐  ── App nusxa 1 (3001)
  │ Mijoz  │ ──── │ Nginx  │  ── App nusxa 2 (3002)
  └────────┘       └────────┘  ── App nusxa 3 (3003)
                  (upstream blok — server ro'yxati)

  ALGORITMLAR (qaysi nusxaga yuborish):

  1) ROUND-ROBIN (default — navbat bilan):
     1nusxa1, 2nusxa2, 3nusxa3, 4nusxa1, ... (teng aylanma)
      eng oddiy, ko'p holatda yetarli

  2) least_conn (eng kam ulanishga):
      hozir ENG KAM faol ulanishi bor nusxaga yuboradi
      so'rovlar har xil davom etganda yaxshi (ba'zi sekin)

  3) ip_hash (IP bo'yicha — yopishqoq):
      bir mijoz (IP) DOIM bitta nusxaga (session yopishqoqligi)
      sessiya serverda saqlansa kerak (lekin Redis yaxshiroq — 5.21)

  WEIGHT (vazn): server backend1 weight=3;   3x ko'p yuk (kuchli mashina)

  PASSIV SALOMATLIK TEKSHIRUVI (health check — nusxa yiqilsa chiqarib tashlash):
  server 127.0.0.1:3001 max_fails=3 fail_timeout=30s;
     │                  │            └─ 30s davomida chiqarib tur, keyin qayta urin
     │                  └─ 3 marta xato bo'lsa — "o'lik" deb belgila
     server 127.0.0.1:3002 backup;    ZAXIRA (asosiylar yiqilsagina ishlaydi)
     server 127.0.0.1:3003 down;      qo'lda O'CHIRILGAN (texnik ishlar uchun)

   Passiv: Nginx real so'rovlardagi xatoni sanaydi (alohida tekshirmaydi)

Load balancer — yukni bir necha ilova nusxasiga taqsimlaydi (gorizontal masshtab — 9.9). Nginx'da nusxalar upstream blokida sanab o'tiladi, algoritm esa qaysi nusxaga yuborishni belgilaydi: round-robin (default — navbat bilan teng aylanma: 1231...; eng oddiy, ko'p holatda yetarli); least_conn (eng kam faol ulanishi bor nusxaga — so'rovlar har xil davom etganda yaxshi, ba'zilari sekin bo'lsa); ip_hash (mijoz IP'si bo'yicha — bir mijoz doim bitta nusxaga tushadi, ya'ni session yopishqoqligi — sticky session). ip_hash sessiya serverda saqlanganda kerak bo'ladi, lekin zamonaviy yondashuv — sessiyani Redis'da saqlash 5.21-bob, shunda nusxalar stateless bo'ladi va har qanday algoritm ishlaydi (9.9: 2.x — stateless masshtab). weight=N parametri — kuchliroq mashinaga ko'proq yuk berish uchun (server backend1 weight=3;). Passiv salomatlik tekshiruvi: Nginx'ning bepul (open source) versiyasi nusxalarni real so'rovlar orqali kuzatadi — max_fails=3 fail_timeout=30s bilan bir nusxa 30 soniya ichida 3 marta xato bersa, uni vaqtincha "o'lik" deb belgilab, so'rov yubormaydi, keyin qayta urinib ko'radi (alohida tekshiruv so'rovi yubormaydi — shuning uchun "passiv"; faol/active health check faqat NGINX Plus'da bor). backup — zaxira nusxa (asosiylar yiqilgandagina ishga tushadi); down — nusxani qo'lda o'chirish (masalan, texnik ishlar paytida — config'dan olib tashlamasdan).

2.6. Config strukturasi: kontekstlar (http/server/location)

text
  NGINX CONFIG — ICHMA-ICH bloklar (context — kontekst):

  # /etc/nginx/nginx.conf
  user www-data;                     global (main context)
  worker_processes auto;             har yadroga 1 worker 2.3-bob

  events { ... }                     ulanish sozlamalari

  http {                             HTTP konteksti (barcha web)
      gzip on;                       bu yerda — barcha server'ga ta'sir
      include /etc/nginx/sites-enabled/*;    saytlarni ulaydi

      upstream backend { ... }       load balancer guruhi 2.5-bob

      server {                       bitta sayt/domen (virtual host)
          listen 80;                 qaysi port
          server_name saytim.uz;     qaysi domen

          location / {               URL yo'liga qarab qoida 2.7-bob
              proxy_pass http://backend;
          }
          location /static/ { ... }  boshqa yo'l — boshqa qoida
      }
  }

   Ichki blok tashqi sozlamani MEROS oladi (gzip http'da  hamma server'da)
   Direktiva ";" bilan tugaydi; blok "{ }" bilan

Nginx configichma-ich bloklar (kontekst — context) tizimi. Asosiy fayl /etc/nginx/nginx.conf. Tashqaridan ichkariga: main (global — user, worker_processes), events (ulanish sozlamalari), http (barcha web sozlamalari — gzip, include), uning ichida upstream (load balancer guruhi — 2.5) va server (bitta sayt/domen — virtual host: listen qaysi port, server_name qaysi domen), uning ichida esa location (URL yo'liga qarab qoida — 2.7). Eng muhim qoida: ichki blok tashqi sozlamalarni meros oladi (gzip on; http'da yozilsa — barcha server va location'da ishlaydi; lekin location'da qayta yozilsa — o'sha joyda ustun bo'ladi). Har direktiva ; bilan, har blok { } bilan tugaydi. Ubuntu'da odatda saytlar /etc/nginx/sites-available/da yoziladi va sites-enabled/ga symlink qilinadi (include orqali ulanadi).

2.7. location matching (=, ^~, ~, prefix — prioritet)

text
  LOCATION — URL yo'liga qarab qaysi qoida ishlashini belgilaydi.
  MUHIM: Nginx eng MOS location'ni QAT'IY PRIORITET bilan tanlaydi:

  PRIORITET (yuqoridan pastga — birinchi mos kelgani g'olib):

  1) location = /exact       ANIQ moslik (eng yuqori, tezda tugaydi)
                              "/exact" ga AYNAN teng bo'lsa

  2) location ^~ /images/    PREFIX (^~ — regex'ni TO'XTATADI)
                              shu prefiks mos kelsa, regex tekshirilmaydi

  3) location ~ \.php$       REGEX (~ katta-kichik farqli, ~* farqsiz)
     location ~* \.(jpg)$     config'da YOZILISH tartibida (birinchi mos)

  4) location /some/path     oddiy PREFIX (eng UZUN mos kelgani)
                              regex topilmasa — shu

  MISOL ("/images/logo.png" so'rovi uchun):
  location = /images/logo.png   1 (aniq) g'olib
  location ^~ /images/          2 (regex'siz)
  location ~* \.png$            3 (regex)
  location /                    4 (eng umumiy)

   Aniq (=) > prefix(^~) > regex(~) > oddiy prefix > "/" (fallback)

location — URL yo'liga qarab qaysi qoida qo'llanishini belgilaydi, va Nginx eng mos location'ni qat'iy prioritet bo'yicha tanlaydi (bu eng ko'p chalkashtiriladigan mavzu). Prioritet tartibi: (1) location = /pathaniq (exact) moslik, URL aynan teng bo'lsa — eng yuqori, darhol tugaydi; (2) location ^~ /prefix/prefiks, mos kelsa regex tekshiruvini to'xtatadi; (3) location ~ regex (katta-kichik harf farqli) / ~* (farqsiz) — regex, config'da yozilish tartibida birinchi mos kelgani; (4) location /prefix — oddiy prefiks, eng uzun mos kelgani (regex topilmaganda). Yodda saqlash: aniq (=) > ^~ prefiks > regex (~) > oddiy prefiks > / (fallback — hamma narsaga mos). Masalan location / { ... } — barcha so'rovlarga mos keladigan eng umumiy qoida (ko'pincha proxy_pass shu yerda). Noto'g'ri prioritet — eng keng config xatosi (statik fayl proxy'ga ketib qoladi).

2.8. proxy_pass va proxy header'lari (X-Forwarded-For, Host)

text
  proxy_pass — so'rovni orqadagi ilovaga UZATADI:
  location /api/ {
      proxy_pass http://localhost:3000;    /api/*  Node 3000'ga
  }

  MUAMMO: Nginx so'rovni uzatganda ilova ASL mijozni KO'RMAYDI:
  - ilovaga so'rov Nginx'dan keladi  req.ip = 127.0.0.1 (Nginx!)
  - asl mijoz IP, domen, protokol YO'QOLADI

  YECHIM: header'larni QO'LDA uzatish (proxy_set_header):
  proxy_set_header Host              $host;                  asl domen
  proxy_set_header X-Real-IP         $remote_addr;           mijoz IP
  proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;   IP zanjiri
  proxy_set_header X-Forwarded-Proto $scheme;                http yoki https

   $proxy_add_x_forwarded_for: mavjud zanjirga mijoz IP'sini QO'SHADI
   ilova bu header'lardan asl mijozni o'qiydi (Express: app.set('trust proxy'))

   Bu header'larsiz: log'da hamma IP — Nginx; HTTPS aniqlanmaydi; redirect buziladi

proxy_pass — so'rovni orqadagi ilovaga uzatuvchi direktiva (proxy_pass http://localhost:3000;). Lekin muhim muammo: Nginx so'rovni uzatganda, ilova nuqtai nazaridan so'rov Nginx'dan keladi — ya'ni req.ip 127.0.0.1 bo'ladi (asl mijoz emas!), domen va protokol (http/https) yo'qoladi. Yechim — header'larni qo'lda uzatish (proxy_set_header): Host $host (asl domen), X-Real-IP $remote_addr (mijozning haqiqiy IP'si), X-Forwarded-For $proxy_add_x_forwarded_for (IP zanjiri — bir necha proxy bo'lsa, mavjud zanjirga mijoz IP'sini qo'shadi), X-Forwarded-Proto $scheme (http yoki https). Ilova bu header'lardan asl mijozni o'qiydi (Express'da app.set('trust proxy', 1)). Bu header'larsiz: barcha log'larda IP 127.0.0.1 ko'rinadi, HTTPS aniqlanmaydi, redirect'lar buziladi. Xavfsizlik: X-Forwarded-Forga faqat ishonchli proxy'dan kelganida ishon (set_real_ip_from) — aks holda mijoz IP'ni soxtalashtirishi mumkin.

2.9. gzip / brotli (javobni siqish)

text
  GZIP — javobni siqib yuboradi (trafik kamayadi, sahifa tez yuklanadi):

  Brauzer:  Accept-Encoding: gzip       "siqilgan qabul qilaman"
  Nginx:    Content-Encoding: gzip      "siqib yubordim"

  http {
      gzip on;                          yoqish
      gzip_types text/css application/javascript application/json;   qaysi turlar
      gzip_min_length 1024;             1KB'dan kichigini siqma (foydasiz)
      gzip_comp_level 5;                siqish darajasi (1 tez  9 zich)
  }

  NATIJA: matn fayllar (HTML/CSS/JS/JSON) ~70-80% kichrayadi
   rasm/video (jpg, mp4) ALLAQACHON siqilgan — qayta siqma (foydasiz)

  BROTLI — gzip'ga muqobil (yanada zichroq, modul kerak):
   CDN/zamonaviy setup'da; gzip — universal va yetarli

   gzip CPU yeydi, lekin tarmoq tejaydi — matn uchun har doim foydali

gzip — javobni siqib yuboruvchi mexanizm: trafik kamayadi, sahifa tezroq yuklanadi. Ishlash tartibi: brauzer Accept-Encoding: gzip deb so'raydi, Nginx siqib Content-Encoding: gzip bilan qaytaradi (brauzer ochadi — shaffof). Sozlash (http blokida): gzip on, gzip_types (qaysi MIME turlarni siqish — text/css, application/javascript, application/json), gzip_min_length 1024 (kichik fayllarni siqish foydasiz — siqish overhead'i o'zidan katta), gzip_comp_level 5 (1 — tez/kam siqadi, 9 — sekin/zich; 5-6 — muvozanat). Matn fayllar (HTML/CSS/JS/JSON) ~70-80% kichrayadi — katta tejamkorlik. Lekin rasm/video (jpg, png, mp4) allaqachon siqilgan — ularni qayta siqish foydasiz (faqat CPU yeydi). Brotli — gzip'ga zamonaviy muqobil (yanada zichroq, lekin alohida modul kerak); gzip esa universal va aksariyat holatda yetarli.

2.10. Statik fayl serving va cache

text
  STATIK FAYL — Nginx diskdan TO'G'RIDAN beradi (ilova kerak emas):

  location /static/ {
      root /var/www/myapp;             /static/a.png  /var/www/myapp/static/a.png
      # alias /var/www/files/;         (alternativa: yo'lni ALMASHTIRADI)
      expires 30d;                     brauzer 30 kun cache qilsin
      add_header Cache-Control "public, immutable";
  }

  root vs alias (chalkashtirmaslik kerak):
  root  /var/www;  + so'rov /static/a.png  /var/www/static/a.png  (yo'l QO'SHILADI)
  alias /data/;    + so'rov /static/a.png  /data/a.png            (prefix ALMASHADI)

  SPA (React/Vue build) — try_files bilan:
  location / {
      try_files $uri $uri/ /index.html;    fayl topilmasa  index.html
  }                                         (client-side routing uchun MAJBURIY)

   Statik fayl Nginx'dan ~10x tez (Node band bo'lmaydi); cache bilan yanada

Statik fayl serving — Nginx fayllarni diskdan to'g'ridan beradi (ilova ishtirokisiz, ~10x tez). root direktivasi yo'lni belgilaydi (root /var/www/myapp; + so'rov /static/a.png /var/www/myapp/static/a.png — yo'l qo'shiladi). alias — alternativa, lekin prefiksni almashtiradi (chalkashtirmaslik kerak — bu ko'p xato manbai). Cache: expires 30d va Cache-Control header'lari brauzerga faylni necha vaqt saqlashni aytadi (qayta yuklamaydi — tezlik). SPA (React/Vue/Angular build — frontend) uchun try_files $uri $uri/ /index.html; majburiy: foydalanuvchi /dashboardga to'g'ridan kirsa, diskda bunday fayl yo'q — try_files topilmasa index.htmlga qaytaradi, va client-side routing (11.9 — React Router) ishlaydi. Busiz SPA'ning ichki sahifalari 404 beradi (Xato 6).

2.11. Rate limiting (limit_req — so'rovlarni cheklash)

text
  RATE LIMITING — bir mijoz NECHA so'rov yuborishini cheklaydi (himoya):
   brute-force, DDoS, abuse'dan himoya 5.20-bob

  ALGORITM: "leaky bucket" (teshik chelak — bir maromda oqib chiqadi)

  http {
      # zona aniqlash: mijoz IP bo'yicha, 10MB xotira, 10 so'rov/sek
      limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
  }

  location /api/ {
      limit_req zone=api burst=20 nodelay;    qoidani qo'llash
  }                  │          │       └─ burst ichidagini DARROV bajar
                     │          └─ 20 ta qo'shimcha "portlash"ga ruxsat
                     └─ qaysi zona

  rate=10r/s    sekundiga 10 so'rov (1r/m  daqiqasiga 1 — sekin xizmat)
  burst=20      vaqtinchalik portlash (navbatda 20 ta kutadi)
  nodelay       burst ichidagini darrov bajar (kechiktirmay); ortig'iga 503

   Login/API'da MUHIM 5.20-bob; rate'siz — bot brute-force qiladi

Rate limiting — bir mijoz ma'lum vaqtda necha so'rov yuborishini cheklash (brute-force, DDoS, abuse'dan himoya — 5.20). Nginx "leaky bucket" (teshik chelak — so'rovlar bir maromda "oqib chiqadi") algoritmini ishlatadi. Ikki qadam: (1) http blokida zona aniqlashlimit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; (mijoz IP bo'yicha, 10m — 10MB xotira holatlarni saqlash uchun, rate=10r/s — sekundiga 10 so'rov; sekundiga birdan kam kerak bo'lsa rate=30r/m — daqiqasiga); (2) location'da qo'llashlimit_req zone=api burst=20 nodelay;. burst=20 — vaqtinchalik "portlash"ga ruxsat (20 ta ortiqcha so'rov navbatda kutadi), nodelay — burst ichidagilarni darrov bajaradi (kechiktirmay), undan ortig'iga 503 qaytaradi. Login va API endpoint'larida muhim himoya: rate limiting'siz bot parolni cheksiz urinib (brute-force) topadi yoki serverni so'rovga ko'mib tashlaydi.

2.12. Nginx vs Apache (qisqacha)

text
  NGINX vs APACHE (ikki eng mashhur web server):

  ┌──────────────┬─────────────────────┬──────────────────────┐
  │              │ NGINX               │ APACHE (httpd)        │
  ├──────────────┼─────────────────────┼──────────────────────┤
  │ Model        │ event-driven (async)│ process/thread-per-req│
  │ Statik fayl  │ juda tez            │ sekinroq              │
  │ Parallel ko'p │ a'lo (kam RAM)      │ ko'p RAM yeydi        │
  │ Config        │ markaziy (block)    │ .htaccess (per-dir)   │
  │ Reverse proxy │ mukammal (asosiy)   │ mumkin (qo'shimcha)   │
  │ Modul         │ compile/dynamic     │ ko'p, dinamik yuklash │
  └──────────────┴─────────────────────┴──────────────────────┘

  QACHON:
  - Nginx  reverse proxy, statik, yuqori yuk, mikroservis oldida (2026 default)
  - Apache  eski PHP loyiha, .htaccess kerak, shared hosting

   Zamonaviy backend (Node/Python) deyarli DOIM Nginx ortida

Nginx vs Apache — ikki eng mashhur web server. Asosiy farq arxitekturada: Nginx event-driven (asinxron — 2.3), Apache an'anaviy process/thread-per-request (har so'rovga alohida — ko'p parallel ulanishda RAM tugaydi). Nginx statik fayl va yuqori yukda ancha tez va tejamkor, config markaziy (bloklar); Apache esa .htaccess (har papkada sozlama — moslashuvchan, lekin sekinroq) va dinamik modullar bilan kuchli. Qachon qaysi: zamonaviy reverse proxy, statik serving, yuqori yuk, mikroservis uchun — Nginx (2026 standart tanlov); eski PHP loyihalar, .htaccess kerak bo'lgan shared hosting uchun — Apache. Zamonaviy backend (Node/Python) deyarli doim Nginx ortida turadi. Yana bir muqobil — Caddy (avtomatik HTTPS bilan, soddaroq), lekin Nginx hamon eng keng tarqalgan.

2.13. SSL/TLS chuqurroq: versiyalar, cipher, HSTS

text
  SSL/TLS TERMINATION — Nginx HTTPS'ni hal qiladi (ilova oddiy HTTP'da — 2.4):

  server {
      listen 443 ssl;
      ssl_certificate     .../fullchain.pem;    sertifikat (public + zanjir)
      ssl_certificate_key .../privkey.pem;       maxfiy kalit (600 ruxsat!)

      # QAYSI TLS versiyalar (eski, buzilganlarini O'CHIRISH):
      ssl_protocols TLSv1.2 TLSv1.3;             1.0/1.1 xavfli — ishlatilmaydi
      ssl_ciphers HIGH:!aNULL:!MD5;              kuchli shifr to'plami
      ssl_prefer_server_ciphers on;              server tanlaydi (mijoz emas)

      # HSTS — brauzerga "doim HTTPS ishlat" deb aytadi (downgrade himoyasi):
      add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
  }

   TLS 1.0/1.1 — 2020'dan buzilgan hisoblanadi; faqat 1.2 va 1.3 qoladi
   HSTS'dan keyin brauzer HTTP so'rovni ham HTTPS'ga o'zi aylantiradi

SSL/TLS chuqurroq. listen 443 ssl bilan SSL termination yoqiladi 2.4-bob: brauzer bilan Nginx orasida shifrlangan (HTTPS), Nginx bilan ilova orasida oddiy HTTP (ichki, ishonchli tarmoq). Sertifikat va kalit — ssl_certificate (public zanjir — fullchain.pem) va ssl_certificate_key (maxfiy kalit — privkey.pem, ruxsati 600 bo'lishi shart). Muhim xavfsizlik sozlamalari: ssl_protocols TLSv1.2 TLSv1.3 — eski, buzilgan TLS 1.0/1.1 versiyalarini o'chiradi (2020'dan xavfli hisoblanadi); ssl_ciphers — ruxsat etilgan shifr to'plami (zaif shifrlar chiqarib tashlanadi); ssl_prefer_server_ciphers on — shifrni server tanlaydi. HSTS (Strict-Transport-Security) — brauzerga "bu domenga endi doim HTTPS orqali kir" deb aytuvchi header: undan keyin brauzer HTTP so'rovni ham o'zi HTTPS'ga aylantiradi (downgrade hujumidan himoya). Amalda bu sozlamalarni Certbot avtomatik yozadi 10.7-bob, lekin ular nima ekanini bilish kerak. always bayrog'i — header xato javoblarda (4xx/5xx) ham qo'shilishini ta'minlaydi.

2.14. proxy_buffering va keepalive (proxy unumdorligi)

text
  PROXY BUFFERING — Nginx ilova javobini BUFERGA yig'adi, keyin mijozga beradi:

  proxy_buffering on;               (default yoqilgan) javobni buferlab uzatadi
  proxy_buffers 8 16k;             8 ta 16KB bufer
  proxy_buffer_size 16k;           birinchi qism (header) uchun

   FOYDA: sekin mijoz ilovani band qilmaydi (Nginx javobni oladi,
    ilovani bo'shatadi, keyin mijozga o'z tezligida beradi)
   O'CHIRISH kerak: SSE, streaming, real-time javob (proxy_buffering off;)

  UPSTREAM KEEPALIVE — Nginxilova ulanishini QAYTA ishlatadi (tez):

  upstream backend {
      server 127.0.0.1:3000;
      keepalive 32;               32 ta ochiq ulanishni saqla (qayta ochma)
  }
  location / {
      proxy_pass http://backend;
      proxy_http_version 1.1;     keepalive uchun MAJBURIY
      proxy_set_header Connection "";    "close" header'ni tozala (ulanish ochiq qolsin)
  }

   keepalive'siz: har so'rovga yangi TCP ulanish (sekin, port tugashi mumkin)

proxy_buffering — Nginx orqadagi ilova javobini avval o'z buferiga yig'ib, keyin mijozga uzatadi (default yoqilgan). Foydasi: sekin mijoz (masalan, mobil internet) ilovani band qilib turmaydi — Nginx javobni ilovadan tez oladi, ilovani bo'shatadi va keyin javobni mijozga o'z tezligida beradi. Buferlarni proxy_buffers va proxy_buffer_size sozlaydi. Istisno: streaming, Server-Sent Events (SSE) yoki real-time javoblar uchun buferni o'chirish kerak (proxy_buffering off;) — aks holda javob buferda ushlanib qoladi va mijozga darhol yetmaydi. Upstream keepalive — Nginx bilan ilova orasidagi TCP ulanishni qayta ishlatish (har so'rovga yangi ulanish ochmaslik): upstream blokida keepalive 32;, va location'da proxy_http_version 1.1; bilan proxy_set_header Connection ""; (standart Connection: close header'ini tozalash). Bu — yuqori yukda unumdorlikni sezilarli oshiradi (ulanish ochish/yopish qimmat operatsiya; bunda ochiq ulanishlar qayta ishlatiladi).

2.15. proxy_cache: javoblarni keshlash

text
  PROXY CACHE — Nginx ilova javobini vaqtincha SAQLAYDI (ilova qayta hisoblamaydi):

  http {
      # Kesh papkasi va zonasi (holatlar RAM'da, fayllar diskda):
      proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=app_cache:10m
                       max_size=1g inactive=60m;
  }

  location /api/products {
      proxy_cache app_cache;                   qaysi zona
      proxy_cache_valid 200 302 10m;           200/302 javobni 10 daqiqa saqla
      proxy_cache_valid 404 1m;                404'ni 1 daqiqa
      proxy_cache_key "$scheme$request_method$host$request_uri";
      add_header X-Cache-Status $upstream_cache_status;    HIT/MISS ko'rsat
      proxy_pass http://backend;
  }

   X-Cache-Status: HIT (keshdan) | MISS (ilovadan) | EXPIRED | BYPASS
   FAQAT o'zgarmaydigan GET javoblarni keshla — foydalanuvchiga xos (login) EMAS

proxy_cache — Nginx orqadagi ilova javoblarini vaqtincha saqlab, bir xil so'rov qayta kelganda ilovani bezovta qilmasdan keshdan javob beradi (ilova yuki keskin kamayadi, javob tezlashadi). Ikki qadam: (1) http blokida kesh joyini aniqlash — proxy_cache_path (disk papkasi, keys_zone — kalitlar uchun RAM zonasi, max_size — maksimal disk hajmi, inactive — ishlatilmasa qancha vaqtdan keyin o'chirish); (2) location'da yoqishproxy_cache app_cache; va proxy_cache_valid 200 10m; (qaysi status kodni qancha saqlash). X-Cache-Status header'i ($upstream_cache_status) keshdan (HIT) yoki ilovadan (MISS) kelganini ko'rsatadi — sozlashda foydali. Muhim ogohlantirish: faqat o'zgarmaydigan, umumiy GET javoblarni keshlash kerak (masalan, mahsulotlar ro'yxati). Foydalanuvchiga xos javoblarni (login holati, savat, shaxsiy sahifa) keshlash xavfli — bir foydalanuvchining ma'lumoti boshqasiga ko'rinib qolishi mumkin. FastCGI orqali ishlaydigan PHP uchun ekvivalenti — fastcgi_cache (bir xil tamoyil).

2.16. Logging: access va error log

text
  NGINX LOG — ikki asosiy jurnal:

  /var/log/nginx/access.log    har SO'ROV (kim, qachon, qaysi URL, status)
  /var/log/nginx/error.log     XATOLAR (502, config, ruxsat — muammo 1-joyi)

  http {
      # Maxsus log formati (masalan, javob vaqtini qo'shish):
      log_format main '$remote_addr - $remote_user [$time_local] '
                      '"$request" $status $body_bytes_sent '
                      '"$http_referer" "$http_user_agent" '
                      'rt=$request_time';          so'rov qancha davom etdi

      access_log /var/log/nginx/access.log main;
      error_log  /var/log/nginx/error.log warn;    daraja: debug<info<warn<error
  }

  # Statik/salomatlik so'rovlarini log qilmaslik (jurnalni tozalash):
  location /health { access_log off; return 200 "ok"; }

   error.log — HAR muammoda BIRINCHI qaraydigan joy (aniq sabab shu yerda)

Logging. Nginx ikki jurnal yuritadi: access.log — har bir so'rovni yozadi (mijoz IP'si, vaqt, so'ralgan URL, status kod, uzatilgan bayt) — trafik tahlili va statistika uchun; error.log — xatolarni yozadi (502, config muammosi, fayl ruxsati) — har muammoda birinchi qaraydigan joy, aniq sabab odatda shu yerda ko'rsatiladi. log_format bilan maxsus format yaratish mumkin — masalan, $request_time (so'rov qancha davom etgani — sekin endpoint'larni topishga yordam beradi) yoki $upstream_response_time (ilova qancha javob bergani) qo'shish. error_log darajasi (warn, error, debug) — qancha batafsil yozilishini belgilaydi (production'da warn, muammo qidirilganda vaqtincha debug). Tez-tez so'raladigan, ahamiyatsiz endpoint'lar (masalan, salomatlik tekshiruvi /health) uchun access_log off; bilan logni o'chirish jurnalni toza va o'qishga qulay saqlaydi.

2.17. rewrite va return: URL qayta yozish

text
  URL O'ZGARTIRISH — ikki yo'l:

  1) return — TEZ, oddiy (redirect yoki tayyor javob):
     return 301 https://$host$request_uri;     doimiy redirect  HTTPS 2.4-bob
     return 200 "OK";                           to'g'ridan javob (ilovasiz)
     return 444;                                ulanishni jimgina yop (bot)

  2) rewrite — REGEX bilan URL'ni ichki qayta yozish:
     rewrite ^/old-blog/(.*)$ /blog/$1 permanent;    eskiyangi yo'l (301)
     rewrite ^/user/(\d+)$ /profile?id=$1 last;       ichki qayta yozish
        │                              │      └─ bayroq (last/break/redirect/permanent)
        └─ moslik namunasi (regex)     └─ yangi yo'l ($1 = guruh)

  BAYROQLAR: permanent(301) | redirect(302) | last(qayta location izla) | break(shu yerda to'xta)

   Oddiy redirect uchun "return" afzal (tez); murakkab qayta yozishga "rewrite"

rewrite va return — URL'ni o'zgartirishning ikki usuli. return — tez va oddiy: to'g'ridan status kod bilan javob qaytaradi. Eng ko'p ishlatiladigani — HTTPHTTPS redirect (return 301 https://$host$request_uri; — 2.4, Misol 5); yana return 200 "..." (ilovasiz tayyor javob, masalan salomatlik tekshiruvi) yoki return 444 (ulanishni javobsiz yopish — zararli botlarga). rewriteregex bilan URL'ni qayta yozadi: rewrite ^/old/(.*)$ /new/$1 permanent; (eski yo'lni yangisiga ko'chirish, $1 — regex guruhi). Bayroqlar yakunni belgilaydi: permanent (301 redirect), redirect (302 — vaqtinchalik), last (yangi yo'l bilan location qidiruvini qaytadan boshlash), break (shu blokda to'xtash). Amaliy qoida: oddiy redirect uchun har doim return afzal (u tezroq va o'qishga aniqroq); rewrite esa faqat regex bilan namunali qayta yozish kerak bo'lganda (masalan, sayt strukturasini ko'chirishda eski havolalarni saqlab qolish uchun).


3. Sintaksis — tez ma'lumotnoma

text
O'RNATISH:    sudo apt install nginx | systemctl enable --now nginx (10.1: 2.6)
TEKSHIRISH:   sudo nginx -t             config sintaksisini tekshir (MAJBURIY)
QAYTA YUKLASH: sudo nginx -s reload | sudo systemctl reload nginx (uzilishsiz)
FAYLLAR:      /etc/nginx/nginx.conf | /etc/nginx/sites-available/ + sites-enabled/
LOG:          /var/log/nginx/access.log | /var/log/nginx/error.log (xato 1-joy)

KONTEKST 2.6-bob: http { upstream{} server { listen; server_name; location {} } }
LOCATION 2.7-bob: = aniq | ^~ prefix(regex'siz) | ~ regex | ~* regex-farqsiz | /prefix
PROXY 2.8-bob:    proxy_pass http://localhost:3000; + proxy_set_header Host $host;
HEADER 2.8-bob:   X-Real-IP $remote_addr | X-Forwarded-For $proxy_add_x_forwarded_for
UPSTREAM 2.5-bob: upstream backend { least_conn; server 127.0.0.1:3001; server :3002; }
HEALTH 2.5-bob:   server :3001 max_fails=3 fail_timeout=30s; | backup | down
STATIK 2.10-bob:  root /var/www; | try_files $uri $uri/ /index.html; | expires 30d;
GZIP 2.9-bob:     gzip on; gzip_types text/css application/json; gzip_min_length 1024;
RATE 2.11-bob:    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
                limit_req zone=api burst=20 nodelay;
SSL 2.13-bob:     listen 443 ssl; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL;
HSTS 2.13-bob:    add_header Strict-Transport-Security "max-age=31536000" always;
KEEPALIVE2.14-bob:upstream{ keepalive 32; } + proxy_http_version 1.1; Connection "";
CACHE 2.15-bob:   proxy_cache_path ... keys_zone=z:10m; | proxy_cache z; proxy_cache_valid 200 10m;
LOG 2.16-bob:     access_log /var/log/nginx/access.log; error_log ... warn; access_log off;
REWRITE 2.17-bob: return 301 https://$host$request_uri; | rewrite ^/old/(.*)$ /new/$1 permanent;
WEBSOCKET:      proxy_http_version 1.1; Upgrade $http_upgrade; Connection "upgrade";
BUFFERING2.14-bob:proxy_buffering on;  (streaming/SSE uchun: off)
UPLOAD:         client_max_body_size 20M;    katta yuklash uchun (default 1M)

4. Batafsil kod namunalari

Misol 1 — Eng oddiy reverse proxy (Node 3000'ga — 2.8)

nginx
# /etc/nginx/sites-available/myapp  (sudo nano bilan yaratamiz)
server {
    listen 80;                              # 80-portda tinglaydi (HTTP)
    server_name saytim.uz www.saytim.uz;    # qaysi domen(lar) uchun

    location / {                            # barcha so'rovlar (2.7)
        proxy_pass http://localhost:3000;   # ichki Node ilovaga uzat (2.8)

        # Asl mijoz ma'lumotini ilovaga uzatamiz (2.8 — busiz IP=127.0.0.1)
        proxy_set_header Host              $host;                       # asl domen
        proxy_set_header X-Real-IP         $remote_addr;                # mijoz IP
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;  # IP zanjiri
        proxy_set_header X-Forwarded-Proto $scheme;                     # http/https
    }
}
bash
# Saytni yoqamiz (symlink) va tekshiramiz
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t                               # config to'g'rimi? (MAJBURIY — Xato 4)
sudo systemctl reload nginx                 # uzilishsiz qayta yuklash
#  Endi http://saytim.uz  Nginx  Node 3000 (foydalanuvchi 3000'ni ko'rmaydi)

Misol 2 — Statik SPA (React/Vue build) serve qilish (2.10)

nginx
server {
    listen 80;
    server_name app.saytim.uz;

    root /var/www/myapp/dist;               # build papkasi (npm run build natijasi)
    index index.html;

    location / {
        # SPA uchun MAJBURIY: fayl topilmasa  index.html (client routing — 11.9)
        try_files $uri $uri/ /index.html;   # /dashboard  index.html (404 emas)
    }

    # Statik resurslarni uzoq cache qilamiz (hash'li nom — o'zgarmaydi)
    location /assets/ {
        expires 1y;                         # 1 yil brauzer cache (2.10)
        add_header Cache-Control "public, immutable";
    }
}

Misol 3 — Load balancer (bir necha nusxa — upstream — 2.5)

nginx
# upstream — yuk taqsimlanadigan nusxalar guruhi (http kontekstida)
upstream node_backend {
    least_conn;                             # eng kam ulanishli nusxaga (2.5)
    server 127.0.0.1:3001;                  # nusxa 1
    server 127.0.0.1:3002;                  # nusxa 2
    server 127.0.0.1:3003 weight=2;         # nusxa 3 — 2x ko'p yuk (kuchli)
    server 127.0.0.1:3004 backup;           # zaxira (asosiylar yiqilsa ishlaydi)
}

server {
    listen 80;
    server_name saytim.uz;

    location / {
        proxy_pass http://node_backend;     # guruhga proxy (Nginx taqsimlaydi)
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
#  4 nusxa = PM2 cluster yoki 4 systemd service (10.1: 2.6) turli portlarda

Misol 4 — gzip siqish (global — 2.9)

nginx
# /etc/nginx/nginx.conf ning http { } blokiga qo'shamiz
http {
    gzip on;                                # gzip yoqish
    gzip_vary on;                           # "Vary: Accept-Encoding" (cache to'g'ri)
    gzip_min_length 1024;                   # 1KB'dan kichigini siqma (foydasiz)
    gzip_comp_level 5;                      # 1(tez)..9(zich) — 5 muvozanat
    gzip_types                              # qaysi turlarni siqish (matn)
        text/plain
        text/css
        application/json
        application/javascript
        application/xml
        image/svg+xml;
    #  image/jpeg, video — qo'shma (allaqachon siqilgan — foydasiz, CPU yeydi)
}

Misol 5 — HTTP HTTPS redirect (2.4, 10.7)

nginx
# 80-port (HTTP) — hammasini HTTPS'ga yo'naltiramiz (xavfsizlik)
server {
    listen 80;
    server_name saytim.uz www.saytim.uz;
    return 301 https://$host$request_uri;   # doimiy redirect (301)  HTTPS
}

# 443-port (HTTPS) — asosiy server (SSL — Certbot qo'shadi — 10.7)
server {
    listen 443 ssl;
    server_name saytim.uz www.saytim.uz;

    ssl_certificate     /etc/letsencrypt/live/saytim.uz/fullchain.pem;   # sertifikat
    ssl_certificate_key /etc/letsencrypt/live/saytim.uz/privkey.pem;     # maxfiy kalit

    location / {
        proxy_pass http://localhost:3000;   # ilova oddiy HTTP'da (SSL termination — 2.4)
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;   # ilova HTTPS'ni biladi
    }
}
#  Sertifikatni Certbot avtomatik oladi/yangilaydi (10.7 — bu yerda qo'lda yozmaymiz)

Misol 6 — Sub-path location: frontend + backend bitta domende (2.7)

nginx
server {
    listen 80;
    server_name saytim.uz;

    # /api/*  backend (Node 3000) — prefix bilan
    location /api/ {
        proxy_pass http://localhost:3000;   # /api/users  Node'ga /api/users
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # /uploads/*  statik fayllar (Node band bo'lmasin — 2.10)
    location /uploads/ {
        root /var/www/myapp;                # /uploads/x.png  /var/www/myapp/uploads/x.png
        expires 7d;
    }

    # qolgan hammasi  frontend SPA (eng umumiy — oxirgi)
    location / {
        root /var/www/myapp/dist;
        try_files $uri $uri/ /index.html;   # SPA routing (2.10)
    }
}
#  Prioritet 2.7-bob: /api/ va /uploads/ aniqroq  ular birinchi; / — fallback

Misol 7 — WebSocket proxy (Socket.io upgrade — 5.13)

nginx
server {
    listen 80;
    server_name chat.saytim.uz;

    location / {
        proxy_pass http://localhost:3000;

        # WebSocket uchun MAJBURIY 3 qator (busiz handshake buziladi — 5.13):
        proxy_http_version 1.1;                       # HTTP/1.1 (1.0 Upgrade'ni qo'llab-quvvatlamaydi)
        proxy_set_header Upgrade    $http_upgrade;     # Upgrade header'ni uzat
        proxy_set_header Connection "upgrade";         # ulanishni "upgrade" qil

        proxy_set_header Host $host;
        proxy_read_timeout 3600s;                      # uzoq ochiq tursin (WS — doimiy)
    }
}
#  Socket.io/WebSocket 5.13-bob — bu 3 qatorsiz ulanmaydi (HTTP'da qoladi yoki 400)

Misol 8 — Rate limiting (login himoyasi — 2.11, 5.20)

nginx
http {
    # Zona: IP bo'yicha, login uchun qattiqroq (5 so'rov/daqiqa)
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    # Umumiy API uchun yumshoqroq (10 so'rov/sek)
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
}

server {
    listen 80;
    server_name saytim.uz;

    location /api/auth/login {
        limit_req zone=login burst=3 nodelay;   # brute-force himoyasi (qattiq)
        proxy_pass http://localhost:3000;
    }

    location /api/ {
        limit_req zone=api burst=20 nodelay;     # umumiy API (yumshoq)
        proxy_pass http://localhost:3000;
    }
}
#  Login'da qattiq limit — parol brute-force imkonsiz (5.20, 14.3)

Misol 9 — Katta fayl yuklash va timeout (5.11 — file upload)

nginx
server {
    listen 80;
    server_name saytim.uz;

    # Katta yuklash uchun (default 1M — rasm/video uchun yetmaydi — Xato 2)
    client_max_body_size 50M;               # 50MB gacha so'rov tanasi

    location /api/upload {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;

        # Sekin/katta yuklashlar uchun timeout'larni oshiramiz
        proxy_connect_timeout 60s;          # ilovaga ulanish kutilishi
        proxy_send_timeout    300s;         # ilovaga yuborish (katta fayl)
        proxy_read_timeout    300s;         # ilovadan javob kutish
    }
}
#  client_max_body_size kichik bo'lsa  413 (Xato 2); timeout kichik  504

Misol 10 — To'liq production server bloki (umumlashma)

nginx
# /etc/nginx/sites-available/myapp — production setup (frontend + API + WS + SSL)
upstream app_backend {
    least_conn;
    server 127.0.0.1:3001;                  # 2 nusxa (load balance — 2.5)
    server 127.0.0.1:3002;
    keepalive 32;                           # ilova bilan ulanishni qayta ishlat (tez)
}

server {                                    # HTTP  HTTPS (2.5)
    listen 80;
    server_name saytim.uz;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;                   # HTTPS + HTTP/2 (tezroq)
    server_name saytim.uz;

    ssl_certificate     /etc/letsencrypt/live/saytim.uz/fullchain.pem;  # 10.7
    ssl_certificate_key /etc/letsencrypt/live/saytim.uz/privkey.pem;

    client_max_body_size 20M;               # yuklash limiti (Misol 9)
    add_header X-Frame-Options "SAMEORIGIN";        # clickjacking himoya (14.x)
    add_header X-Content-Type-Options "nosniff";    # MIME sniff himoya

    # API  backend (load balance + header'lar)
    location /api/ {
        limit_req zone=api burst=20 nodelay;        # rate limit (Misol 8)
        proxy_pass http://app_backend;
        proxy_http_version 1.1;
        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;
    }

    # WebSocket (5.13)
    location /socket.io/ {
        proxy_pass http://app_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }

    # Frontend SPA (statik — 2.10)
    location / {
        root /var/www/myapp/dist;
        try_files $uri $uri/ /index.html;
        expires 1h;
    }
}
#  Bu — real production shabloni: SSL + LB + API + WS + statik + xavfsizlik

Misol 11 — SSL/TLS mustahkamlash va HSTS (2.13)

nginx
server {
    listen 443 ssl http2;
    server_name saytim.uz;

    ssl_certificate     /etc/letsencrypt/live/saytim.uz/fullchain.pem;   # 10.7
    ssl_certificate_key /etc/letsencrypt/live/saytim.uz/privkey.pem;

    # Faqat zamonaviy, xavfsiz TLS versiyalari (1.0/1.1 — buzilgan, o'chirilgan)
    ssl_protocols       TLSv1.2 TLSv1.3;             # 2.13
    ssl_ciphers         HIGH:!aNULL:!MD5;            # kuchli shifr to'plami
    ssl_prefer_server_ciphers on;                    # shifrni server tanlaydi
    ssl_session_cache   shared:SSL:10m;              # TLS handshake keshi (tezlik)

    # HSTS — brauzer bu domenga endi doim HTTPS orqali kiradi (downgrade himoya)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    server_tokens off;                               # Nginx versiyasini yashir (14.x)

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;  # ilova HTTPS'ni biladi (2.8)
    }
}
#  Amalda bu SSL sozlamalarni Certbot avtomatik yozadi 10.7-bob — bu yerda tushunish uchun

Misol 12 — proxy_cache: og'ir GET javobini keshlash (2.15)

nginx
# http { } blokida — kesh joyi va zonasi (bir marta e'lon qilinadi)
http {
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=app_cache:10m
                     max_size=1g inactive=60m;      # 1GB disk, 60 daq ishlatilmasa o'chir
}

server {
    listen 80;
    server_name saytim.uz;

    # Og'ir, kam o'zgaradigan ro'yxatni keshlaymiz (ilova qayta hisoblamaydi)
    location /api/products {
        proxy_cache app_cache;                       # 2.15 zona
        proxy_cache_valid 200 302 10m;               # muvaffaqiyatli javob — 10 daqiqa
        proxy_cache_valid 404 1m;                    # topilmadi — 1 daqiqa
        proxy_cache_key "$scheme$request_method$host$request_uri";
        add_header X-Cache-Status $upstream_cache_status;   # HIT/MISS (DevTools'da ko'rinadi)
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
    }
}
#  FAQAT umumiy, o'zgarmas GET'ni keshla — login/savat/shaxsiy sahifani EMAS (2.15)

5. To'g'ri va noto'g'ri holatlar

1) Ilovani internetga ochish

text
 Node 3000'ni to'g'ridan internetga ochish (firewall'da 3000 ochiq — xavf)
 Faqat 80/443 ochiq; 3000 lokalda; Nginx proxy qiladi (2.4, 10.1: 2.7)

2) Mijoz IP'sini uzatish

text
 proxy_set_header'siz proxy (ilovada barcha IP = 127.0.0.1 — log/rate buziladi)
 X-Real-IP, X-Forwarded-For uzatish + ilovada trust proxy (2.8)

3) Statik fayllar

text
 Rasm/CSS/JS'ni ham Node orqali berish (Node band, sekin)
 Nginx'dan to'g'ridan (root + expires cache — 2.10) — Node faqat /api

4) Config o'zgartirgach

text
 reload qilib darrov, nginx -t qilmasdan (xato bo'lsa — sayt yiqiladi)
 AVVAL "nginx -t", KEYIN "reload" (uzilishsiz, xavfsiz — Xato 4)

5) SPA routing

text
 try_files'siz (foydalanuvchi /dashboard'ga to'g'ri kirsa  404)
 try_files $uri $uri/ /index.html (client routing ishlaydi — 2.10)

6) WebSocket

text
 oddiy proxy_pass (Upgrade header yo'q  handshake buziladi — 400)
 proxy_http_version 1.1 + Upgrade + Connection "upgrade" (Misol 7, 5.13)

7) Rate limiting

text
 Login'ga limit yo'q (bot cheksiz parol urinadi — brute-force)
 limit_req zone qattiq (login 5r/m) — brute-force imkonsiz (2.11, 5.20)

8) TLS versiyalari

text
 Eski TLS 1.0/1.1 ochiq qoldirish (buzilgan — downgrade hujum xavfi)
 ssl_protocols TLSv1.2 TLSv1.3 + HSTS (faqat zamonaviy shifr — 2.13)

9) Javob keshlash

text
 Login/shaxsiy javobni proxy_cache'ga qo'yish (foydalanuvchi ma'lumoti aralashadi)
 Faqat umumiy, o'zgarmas GET (mahsulot ro'yxati) keshlanadi — X-Cache-Status kuzatiladi (2.15)

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — 502 Bad Gateway

Sababi: Nginx orqadagi ilovaga yetib bora olmadi — ilova ishlamayapti (3000 yopiq), noto'g'ri port proxy_pass'da, yoki ilova yiqilgan. Yechimi: ilova ishlayotganini tekshirish (systemctl status myapp, curl localhost:3000 — 10.1: 2.6); proxy_pass'dagi port to'g'riligini aniqlash; /var/log/nginx/error.log ni o'qish (aniq sabab shu yerda). Bu — eng keng tarqalgan Nginx xatosi.

Xato 2 — 413 Request Entity Too Large

Sababi: so'rov tanasi (yuklangan fayl) Nginx limitidan katta — default client_max_body_size faqat 1MB. Yechimi: client_max_body_size 50M; qo'shish (server yoki location blokida — Misol 9), nginx -t && reload. Faqat Nginx'ni emas — ilovaning o'z limitini ham oshirish kerak (Express limit, Multer — 5.11).

Xato 3 — address already in use (80-port band)

Sababi: 80-portni boshqa jarayon (eski Nginx, Apache) ushlab turibdi. Yechimi: sudo ss -tulpn | grep :80 bilan kim ushlab turganini aniqlash (10.1: 2.7); Apache bo'lsa sudo systemctl stop apache2 && sudo systemctl disable apache2; keyin sudo systemctl restart nginx.

Xato 4 — nginx: [emerg] ... unknown directive (config xatosi)

Sababi: config'da sintaksis xatosi (; tushib qolgan, blok yopilmagan, noto'g'ri direktiva). Yechimi: sudo nginx -t — aniq qator va xatoni ko'rsatadi; tuzatib qayta nginx -t, keyin reload. Hech qachon nginx -t'siz reload qilma — xato config sayt ishlamay qolishiga olib keladi.

Xato 5 — 403 Forbidden (statik faylda)

Sababi: Nginx (www-data foydalanuvchi) fayl/papkani o'qiy olmaydi — ruxsat noto'g'ri (10.1: 2.3), yoki index fayl yo'q. Yechimi: ls -l /var/www/myapp bilan ruxsatni tekshirish; sudo chown -R www-data:www-data /var/www/myapp yoki to'g'ri ruxsat berish (chmod 755 papka, 644 fayl); papka yo'lidagi barcha bo'g'inlar x (kirish) ruxsatiga ega bo'lishi shart.

Xato 6 — SPA ichki sahifa 404 Not Found

Sababi: try_files yo'q — foydalanuvchi /dashboardga to'g'ridan kirsa, diskda bunday fayl yo'q 2.10-bob. Yechimi: location / { try_files $uri $uri/ /index.html; } qo'shish — topilmasa index.htmlga qaytaradi, client routing ishlaydi 11.9-bob.

Xato 7 — O'zgarish ko'rinmayapti (eski versiya)

Sababi: config o'zgardi, lekin reload qilinmadi; yoki brauzer/Nginx cache'da eski versiya. Yechimi: sudo systemctl reload nginx (config qayta o'qiladi); brauzerda hard refresh (Ctrl+Shift+R); expires cache bo'lsa — versiyalangan fayl nomi ishlatish (hash — app.a1b2c3.js).


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • Linux server 10.1-bob: Nginx shu serverda, systemd bilan, 80/443-portda ishlaydi (firewall — 2.7).
  • Docker 10.3-bob: Nginx alohida konteyner sifatida; docker-compose da ilova oldida (reverse proxy).
  • SSL/Certbot 10.7-bob: Certbot Nginx config'iga sertifikat qo'shadi (443, avtoyangilanish — Misol 5).
  • WebSocket 5.13-bob: Socket.io uchun Upgrade proxy majburiy (Misol 7).
  • File upload 5.11-bob: client_max_body_size Multer bilan mos bo'lsin (Misol 9, Xato 2).
  • Rate limiting 5.20-bob: Nginx darajasida birinchi himoya qatlami (ilovagacha — Misol 8).
  • Load balancing 9.9-bob: gorizontal masshtab — upstream bir necha nusxa 2.5-bob.
  • API Gateway 9.8-bob: Nginx — oddiy reverse proxy/gateway shakli (mikroservis oldida).
  • Frontend SPA (11.x): React/Vue build'ini Nginx statik beradi (try_files — 2.10).

8. Eng yaxshi amaliyotlar (best practices)

  • nginx -t har doim (reload'dan oldin — xato config'ni oldindan tut — Xato 4).
  • Proxy header'lari to'liq (Host, X-Real-IP, X-Forwarded-For/Proto — asl mijoz ko'rinsin — 2.8).
  • Statikni Nginx'dan (rasm/CSS/JS — Node band bo'lmasin; cache expires — 2.10).
  • gzip yoq (matn fayllar uchun — trafik 70%+ kamayadi; rasm/video'ni qo'shma — 2.9).
  • HTTPS majburiy (HTTP301 redirect; SSL termination — Certbot avtomatik — 2.4, 10.7).
  • Ilova porti yopiq (3000 faqat lokal; firewall'da 80/443 — eng kam ochiqlik — 10.1: 2.7).
  • Rate limiting (login va API'da — brute-force/DDoS himoyasi — 2.11, 5.20).
  • client_max_body_size (yuklash kerak bo'lsa oshir; aks holda 413 — Xato 2).
  • WebSocket'da Upgrade (proxy_http_version 1.1 + Upgrade + Connection — Misol 7).
  • Log'larni kuzat (/var/log/nginx/error.log — muammo 1-joyda; access.log — trafik tahlili).
  • reload ishlat (restart emas)reload uzilishsiz config qayta o'qiydi (mavjud ulanishlar uzilmaydi).
  • Xavfsizlik header'lari (X-Frame-Options, X-Content-Type-Options; server_tokens off; — versiyani yashir — 14.x).
  • TLS versiyalarini cheklash (ssl_protocols TLSv1.2 TLSv1.3; — eski, buzilgan 1.0/1.1 o'chiriladi; HSTS bilan downgrade himoyasi — 2.13).
  • Upstream keepalive (yuqori yukda Nginxilova ulanishini qayta ishlatish — 2.14).
  • Keshni ehtiyotkorlik bilan (proxy_cache faqat umumiy, o'zgarmas GET javoblarga — shaxsiy ma'lumotni keshlamaslik — 2.15).
  • error.logni birinchi qarash (har muammoda aniq sabab shu yerda; kerak bo'lsa log_formatga $request_time qo'shib sekin endpoint'larni topish — 2.16).

9. Amaliy loyiha: "To'liq Production Reverse Proxy"

Bitta serverda frontend SPA, backend API va WebSocket'ni Nginx ortida birlashtirib, SSL, gzip, cache, rate limiting va load balancing bilan to'liq production setup qurish.

Maqsad

10.1'da sozlangan serverda (yoki lokal VM/WSL2) Node.js ilovani va React/Vue build'ini Nginx ortiga qo'yib, bitta domen orqali (/ frontend, /api backend, WebSocket bilan) xavfsiz, tez va masshtablanadigan tarzda xizmat ko'rsatish.

Talablar (requirements)

  1. Nginx o'rnatish: apt install nginx, systemd bilan yoqish (enable --now — 10.1: 2.6).
  2. Reverse proxy: /api/* Node ilova (3000); to'liq proxy header'lar bilan (Misol 1, 6, 2.8).
  3. Statik SPA: React/Vue build'ini /var/www'ga joylab, try_files bilan serve qil (Misol 2, 2.10).
  4. Load balancing: ilovani 2+ nusxada ishga tushir (PM2 cluster/systemd), upstream bilan taqsimla (Misol 3, 2.5).
  5. gzip: matn fayllar uchun yoq (gzip_types, min_length — Misol 4, 2.9).
  6. HTTPS: HTTPHTTPS redirect; SSL (Certbot — yoki lokal self-signed) — Misol 5, 10.7.
  7. WebSocket: Socket.io endpoint uchun Upgrade proxy (Misol 7, 5.13).
  8. Rate limiting: login endpoint'ga qattiq, umumiy API'ga yumshoq limit (Misol 8, 2.11).
  9. Upload: client_max_body_size + timeout (katta fayl yuklash — Misol 9, 5.11).
  10. Tekshirish: nginx -t toza; brauzerda frontend, API javob, WebSocket ulanadi; error.log toza.

Maslahatlar (hint)

  • Har config o'zgarishidan keyin sudo nginx -t && sudo systemctl reload nginx (Xato 4).
  • 502 chiqsa — avval ilova ishlayotganini tekshirish (curl localhost:3000), keyin error.log (Xato 1).
  • location prioritetiga e'tibor berish kerak: /api/ aniqroq / dan oldin tanlanadi 2.7-bob.
  • SPA 404 bersa — try_files borligini tekshirish (Misol 2, Xato 6).
  • WebSocket ulanmasa — Upgrade'ning 3 qatori borligini tekshirish (Misol 7).
  • VPS yo'q bo'lsa — WSL2/Multipass'da xuddi shu setup'ni qur (bepul — 10.1).

"Tayyor" mezonlari (acceptance criteria)

  • http://domen HTTPS'ga redirect bo'ladi, sayt 443'da ochiladi.
  • / frontend SPA'ni ko'rsatadi, ichki sahifa (/dashboard) refresh'da 404 bermaydi.
  • /api/* so'rovlari Node ilovaga to'g'ri proxy bo'ladi, ilova asl mijoz IP'sini ko'radi.
  • Ilova 2+ nusxada ishlaydi, yuk upstream orqali taqsimlanadi.
  • gzip ishlaydi (DevTools'da Content-Encoding: gzip ko'rinadi).
  • WebSocket (Socket.io) ulanadi va real-time ishlaydi.
  • Login'ga ko'p so'rov yuborilsa — 429/503 qaytadi (rate limit).
  • nginx -t toza, error.logda xato yo'q.

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda Nginx'ni reverse proxy va load balancer sifatida chuqur o'rgandik:

  • Nginx nima (web server vs reverse proxy — 2.1); forward vs reverse proxy 2.2-bob; arxitektura (master/worker, event-driven — nega tez — 2.3); reverse proxy afzalliklari (SSL, gzip, cache, statik, xavfsizlik — 2.4).
  • Load balancing (round-robin/least_conn/ip_hash — 2.5); config strukturasi (http/server/location kontekstlari — 2.6); location matching (=/^//prefix prioriteti — 2.7).
  • proxy_pass va header'lar (X-Forwarded-For, Host — 2.8); gzip 2.9-bob; statik fayl va cache (try_files, expires — 2.10); rate limiting (limit_req — 2.11); Nginx vs Apache 2.12-bob.
  • SSL/TLS chuqurroq (ssl_protocols, cipher, HSTS — 2.13); proxy_buffering va upstream keepalive 2.14-bob; proxy_cache (og'ir GET keshi — 2.15); logging (access/error, log_format — 2.16); rewrite/return (URL qayta yozish — 2.17).

Endi siz ilovangni internetga to'g'ri, xavfsiz va tez chiqara olasiz — Node porti yashiriladi, SSL hal qilinadi, statik fayllar tez beriladi, yuk taqsimlanadi. Bu — har production deploy'ning markaziy bo'lagi.

Keyingi bob — 10.3-bob: Docker (image, container, Dockerfile). Endi ilovamiz serverda Nginx ortida ishlayapti, lekin "mening kompyuterimda ishlaydi, serverda ishlamaydi" muammosi hali bor — Node versiyasi, kutubxonalar, OS farqi. Docker shu muammoni hal qiladi: ilovani konteynerga (barcha bog'liqliklari bilan o'ralgan, izolatsiyalangan paket) joylab, har joyda bir xil ishlatadi. Nginx'ni ham, ilovani ham, DB'ni ham konteynerda — bir buyruq bilan ko'tariladigan, ko'chma muhit.


Foydalanilgan rasmiy/ishonchli manbalar

  • Nginx rasmiy hujjati — nginx.org/en/docs/:
    • ngx_http_core_modulelocation, prioritet, root/alias, try_files, client_max_body_size, server_tokens
    • ngx_http_proxy_moduleproxy_pass, proxy_set_header, proxy_buffering, proxy_cache, timeout'lar
    • ngx_http_upstream_module — load balancing (least_conn, ip_hash, weight, max_fails/fail_timeout, backup/down, keepalive)
    • ngx_http_limit_req_module — rate limiting (limit_req_zone, limit_req, burst, nodelay)
    • ngx_http_ssl_modulessl_protocols, ssl_ciphers, ssl_prefer_server_ciphers
    • ngx_http_gzip_module, ngx_http_log_module (access_log, log_format), ngx_http_rewrite_module (return, rewrite)
    • "WebSocket proxying" va "Using nginx as HTTP load balancer" qo'llanmalari
  • NGINX Admin Guide (docs.nginx.com) — Reverse Proxy, HTTP Load Balancing, Content Caching, Rate Limiting, Compression, TLS Termination
  • Mozilla — SSL/TLS konfiguratsiyasi bo'yicha tavsiyalar (zamonaviy cipher/protocol to'plami) va HTTP X-Forwarded-For hujjati

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
10.2-bob: Nginx (reverse proxy, load balancer) — Wisar