20 β To'liq production deploy¶
β¬ οΈ Oldingi: 19 β systemd va process boshqaruvi Β· π README Β· Keyingi: 21 β Nega Kubernetes: arxitektura va lokal klaster β‘οΈ
Bu bobda: kitobning IV qismini yakunlab, hozirgacha o'rganilgan hamma narsani β VPS va xavfsizlik (02, 04), Docker va Compose (06β11), Nginx reverse proxy (16β17), HTTPS (18) va restart siyosati (19) β bitta yaxlit tizimga birlashtiramiz. Namuna "vazifalar" ilovasini noldan production'ga chiqaramiz: bitta
compose.yamldaweb(build yoki GHCR image) +postgres(named volume) +redis+nginx(reverse proxy, 80/443) servislarini,restart: unless-stoppedvadepends_on+healthcheckbilan; maxfiy ma'lumotlarni.env/secret faylda serverda (kodga emas) saqlaymiz. Domen + HTTPS (DNS A record, Certbot webroot, auto-renew), serverga deploy oqimi (git pull/docker compose pullβup -dβ healthcheck kut), zero-downtime asoslari (up -d --no-deps --build web, rolling vs recreate, nginx upstream replica) va to'liq production deploy checklistini (env/secret, backup, healthcheck, log, monitoring, rollback) β keyingi qismlarga ko'prik sifatida β ko'ramiz.
Muammo: bo'laklar tayyor, lekin yaxlit tizim yo'q¶
IV qismda ko'p narsa o'rgandik, lekin har birini alohida ko'rdik:
- 02 va 04-boblarda VPS oldik va uni xavfsizladik (SSH kalit,
ufw,fail2ban). - 06β11-boblarda ilovani Docker ga o'tkazdik, image qurdik va
compose.yamlbilan bir nechta servisni birga ko'tardik. - 16β17-boblarda Nginx ni reverse proxy qildik, 18-bobda HTTPS qo'shdik, 19-bobda esa
restartsiyosati bilan ilovani "tirik" qildik.
Endi savol: bularning hammasini bitta serverda, bitta yaxlit production tizim sifatida qanday birlashtirish kerak? Real ilova faqat node app.js emas β unga ma'lumotlar bazasi (Postgres), cache (Redis), oldida Nginx (TLS bilan), va bularning hammasini boshqaradigan ishonchli deploy oqimi kerak.
Bu bob β aynan shu yaxlitlik. Oxirida sizda real, takrorlanuvchi production deploy bo'ladi.
π Quyidagi
compose.yamlni biz lokal Docker'da haqiqatan ishga tushirib sinab ko'rdik:nginx β web β postgres + rediszanjiri to'liq ishladi (curlnginx orqali web'ga yetib bordi). Real domen, jonli 443 TLS va Certbot esa o'z serveringizda bajariladi β bu qismlar illustrativ, lekin to'g'ri yozilgan.
To'liq stack arxitekturasi¶
Avval umumiy rasmni ko'raylik β internetdan ilovagacha so'rov qaysi yo'ldan o'tadi:
Zanjir shunday: internet β DNS (domen β server IP) β Nginx :443 (TLS tugatish) β web :3000 β postgres + redis. Hammasi bitta Compose stack ichida, bitta ichki tarmoqda. Faqat Nginx tashqariga ochiq (80/443); web, postgres va redis faqat ichki tarmoqda ko'rinadi (xavfsiz β 11 va 17-boblardagi qoida).
Endi shu arxitekturani compose.yaml da yozamiz.
Bitta compose.yaml: butun stack¶
Production stack quyidagi to'rt servisdan iborat. Avval to'liq fayl, keyin muhim joylarni ajratamiz:
services:
web:
# Variant A: serverda image qurish
build: ./app
# Variant B (afzal): CI qurgan tayyor image (14-bob, GHCR)
image: ghcr.io/foydalanuvchi/vazifalar-api:latest
restart: unless-stopped
environment:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/vazifalar
REDIS_URL: redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_healthy
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health',r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))"]
interval: 10s
timeout: 3s
retries: 5
start_period: 10s
db:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: vazifalar
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d vazifalar"]
interval: 10s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
nginx:
image: nginx:1.27-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/app.conf:/etc/nginx/conf.d/default.conf:ro
- certbot-www:/var/www/certbot
- certbot-conf:/etc/letsencrypt
depends_on:
web:
condition: service_healthy
volumes:
db-data:
certbot-www:
certbot-conf:
Bir nechta qoidaga e'tibor bering:
version:kaliti YO'Q. Compose v2'da faylni to'g'ridanservices:bilan boshlaymiz. βversion: "3.8"β eskirgan, yozmang.webdabuildYOKIimage. Serverda qurmoqchi bo'lsangizbuild: ./app; CI tayyor image qurib GHCR'ga yuborgan bo'lsa (14-bob), faqatimage:qoldiring vadocker compose pullqiling β bu production'da afzalroq, chunki serverda kompilyatsiya bo'lmaydi.restart: unless-stoppedhamma servisda β qulasa va server reboot bo'lsa Docker daemon ularni ko'taradi (19-bob).depends_on+condition: service_healthyβwebfaqatdbvacachesog'lom (healthcheck o'tgan) bo'lgandan keyin ishga tushadi. Oddiydepends_onfaqat "ishga tushgan"ni kutadi, "tayyor"ni emas βcondition: service_healthyesa haqiqiy tayyorlikni kutadi.healthcheckβ har servisning "tirikmi va javob beryaptimi" tekshiruvi.webo'zining/healthendpointini,dbpg_isreadyni,cacheredis-cli pingni ishlatadi.- Faqat
nginxdaports:β 80 va 443 tashqariga ochiq.web,db,cachedaports:yo'q β ular faqat ichki tarmoqda, tashqaridan ko'rinmaydi. - Named volume
db-dataβ Postgres ma'lumotlari konteyner o'chsa ham saqlanib qoladi (10-bob).certbot-www/certbot-confβ Certbot challenge va sertifikatlar uchun.
β οΈ
webdabuildham,imageham bo'lsa:docker compose build/up --buildimage:nomi bilan qurib, o'sha nom bilan teglaydi;docker compose pullesaimage:ni tortib oladi. Production'da bitta yo'lni tanlang β odatda CI qurgan image'nipullqilish (qayta qurish emas).
Maxfiy ma'lumot: .env serverda, kodda emas¶
compose.yaml da ${DB_PASSWORD} ni ko'rdingiz β parolni faylga ochiq yozmadik. Compose ${...} o'zgaruvchilarini shu papkadagi .env faylidan o'qiydi:
Bu .env faylni serverda qo'lda yarating va ruxsatini cheklang:
# Faqat egasi o'qiy oladigan qiling
chmod 600 .env
# git'ga tushmasligi uchun .gitignore'ga qo'shing
echo ".env" >> .gitignore
π Maxfiy ma'lumotlarning oltin qoidasi: parol, API kalit, token β hech qachon git repozitoriyga tushmasin. Ular faqat serverdagi
.env(yoki Docker/K8s secret) da yashaydi. Kodda β faqat o'zgaruvchi nomi (${DB_PASSWORD}), qiymat emas. Bu β 04-bobdagi xavfsizlik qoidasining deploy'dagi davomi.
π‘ docker compose config bilan tekshirsangiz, ${DB_PASSWORD} joriy .env qiymati bilan almashtirilganini ko'rasiz β agar .env yo'q bo'lsa, Compose ogohlantirish beradi. Bu β deploydan oldin maxfiylar joyidami yo'qligini tekshirishning oson usuli.
Nginx konteyner: ilova oldida TLS bilan¶
Nginx konteyneri web:3000 ga proxy qiladi. Diqqat: bu β konteyner Nginx (17-bobdagi serverga o'rnatilgan Nginx emas). proxy_pass manzili 127.0.0.1 emas, balki Compose servis nomi β web (ichki DNS, 11-bob). nginx/app.conf:
upstream vazifalar_backend {
server web:3000; # Compose ichki DNS: servis nomi "web"
}
# HTTP (80): ACME challenge uchun joy + HTTPS'ga yo'naltirish
server {
listen 80;
server_name vazifalar.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot; # Certbot webroot challenge'ni shu yerga qo'yadi
}
location / {
return 301 https://$host$request_uri; # HTTP -> HTTPS
}
}
# HTTPS (443): TLS tugatish va web'ga proxy
server {
listen 443 ssl;
http2 on;
server_name vazifalar.example.com;
ssl_certificate /etc/letsencrypt/live/vazifalar.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/vazifalar.example.com/privkey.pem;
location / {
proxy_pass http://vazifalar_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; # ilova HTTPS ekanini bilsin
}
}
Bu config 16β18-boblardagi hamma narsani jamlaydi: HTTPβHTTPS yo'naltirish, TLS tugatish 443'da, X-Forwarded-* headerlar (17-bob), va ACME challenge yo'li (18-bob).
π‘
listen 443 ssl http2;β eski sintaksis. Zamonaviy Nginx'dalisten 443 ssl;va alohidahttp2 on;yoziladi. Bu config'ninginx -tbilan tekshirib ko'ring (pastda mashqlarda) β har deploydan oldin shart.
β οΈ Sertifikat hali yo'q paytda ssl_certificate qatorlari Nginx'ni ishga tushirmaydi (fayl topilmaydi). Real deploy ketma-ketligi: avval faqat 80-portli server bloki bilan Nginx'ni ko'taring, Certbot bilan sertifikat oling, keyin 443 blokni qo'shib nginx -s reload qiling. Buni quyida ko'ramiz.
Domen va HTTPS: DNS + Certbot¶
1. DNS A record. Domen registratoringizda (yoki Cloudflare kabi DNS provayderda) domeningizni server IP'siga ulang:
DNS yoyilishi (propagation) bir necha daqiqadan bir necha soatgacha vaqt oladi. dig vazifalar.example.com +short yoki nslookup bilan server IP'sini ko'rsatishini kuting.
2. Certbot bilan sertifikat (webroot usuli). Nginx konteyneri 80-portda ishlab turganda, Certbot konteyneri bilan sertifikat oling. Compose'ga bir martalik certbot servisi qo'shamiz yoki to'g'ridan ishlatamiz:
# certbot konteyneri webroot orqali sertifikat oladi
# (certbot-www va certbot-conf volume'lari nginx bilan baham ko'riladi)
docker run --rm \
-v certbot-conf:/etc/letsencrypt \
-v certbot-www:/var/www/certbot \
certbot/certbot certonly --webroot -w /var/www/certbot \
-d vazifalar.example.com \
--email admin@example.com --agree-tos --no-eff-email
Sertifikat olingach, Nginx config'iga 443 blokni qo'shib qayta yuklang:
docker compose exec nginx nginx -t # config to'g'rimi
docker compose exec nginx nginx -s reload # uzilishsiz qayta yuklash
3. Auto-renew. Let's Encrypt sertifikati 90 kun amal qiladi. Yangilashni avtomatlashtiring β masalan serverda systemd timer yoki cron (19-bob) bilan har kuni:
# Har kuni yangilashga urinadi; 30 kun qolganda haqiqatan yangilaydi
docker run --rm \
-v certbot-conf:/etc/letsencrypt \
-v certbot-www:/var/www/certbot \
certbot/certbot renew --webroot -w /var/www/certbot \
&& docker compose exec nginx nginx -s reload
βΉοΈ Bu qadamlar β jonli: real domen, DNS yoyilishi va Let's Encrypt server bilan aloqa offline ishlamaydi. Shuning uchun ularni o'z serveringizda bajaring. Config sintaksisini esa lokalda
nginx -tbilan (self-signed sertifikat bilan) tekshirish mumkin.
Deploy oqimi: serverga kelib yangilashni chiqarish¶
Stack tayyor. Endi yangi versiyani production'ga chiqarish oqimini ko'ramiz. Ikki asosiy variant bor:
Variant A β serverda qurish (git pull + build):
ssh deploy@203.0.113.10
cd /opt/vazifalar-api
git pull # yangi kodni torting
docker compose up -d --build # qayta qur va yangi konteynerga almashtir
docker compose ps # holatni tekshir
Variant B β tayyor image'ni tortish (docker compose pull, afzal):
CI (14-bob) image'ni qurib GHCR'ga yuborgan bo'lsa, serverda qurish shart emas β faqat tayyor image'ni torting:
ssh deploy@203.0.113.10
cd /opt/vazifalar-api
docker compose pull # GHCR'dan yangi image'ni tort
docker compose up -d # yangi image bilan konteynerni almashtir
docker compose ps # healthcheck "healthy" bo'lishini kut
up -d ning aqlli tomoni: Compose faqat o'zgargan servislarni qayta yaratadi. Image'i o'zgarmagan db va cache ga tegmaydi β ular ishlab turaveradi. Faqat web ning yangi image'i bo'lsa, faqat web almashtiriladi.
π‘ Deploydan keyin albatta healthcheck'ni kuting va loglarga qarang:
docker compose ps(healthy bo'lishi kerak) vadocker compose logs -f web. "Up qildim, ketdim" emas β "up qildim, sog'lom ekanini ko'rdim, keyin ketdim".
Zero-downtime asoslari¶
"Deploy paytida sayt o'chib qoladimi?" β eng ko'p beriladigan savol. Compose darajasidagi asoslarni ko'ramiz (chuqur rolling update β 23-bobda, Kubernetes bilan).
up -d qanday ishlaydi. docker compose up -d o'zgargan servis uchun yangi konteyner ko'taradi va eskisini to'xtatib almashtiradi. Standart xulq β recreate: eski to'xtaydi, yangi ishga tushadi. Bir oz uzilish bo'lishi mumkin (yangi konteyner ko'tarilguncha).
Faqat web'ni qayta qurish/almashtirish:
# Faqat web servisini qayta qur va almashtir, db/cache'ga tegmasdan
docker compose up -d --no-deps --build web
--no-deps β web ning bog'liqliklarini (db, cache) qayta ishga tushirmaydi; ular ishlab turaveradi. --build β yangi image'ni qurib oladi. Bu β eng ko'p ishlatiladigan tezkor deploy buyrug'i.
Haqiqiy zero-downtime β healthcheck + bir nechta replica. Uzilishni nolga yaqinlashtirish uchun: yangi konteyner ko'tariladi, healthcheck OK bo'lguncha kutiladi, keyin trafik unga o'tadi, eski o'chadi:
Nginx upstream'da bir nechta replica bilan bu yanada silliqlashadi (17-bob):
Bittasi yangilanayotganda ikkinchisi trafikni ushlab turadi. Ammo Compose'da replica boshqaruvi qo'lda; haqiqiy rolling update (bir-bir replica'ni avtomatik almashtirish, healthcheck bilan) β Kubernetes'ning kuchli tomoni, uni 23-bobda chuqur ko'ramiz.
π Rolling vs recreate. Recreate β eskisini o'chirib yangisini ko'taradi (oddiy, qisqa uzilish bo'lishi mumkin). Rolling β replica'larni bir-bir almashtiradi, har doim kamida bittasi ishlab turadi (uzilishsiz). Compose'da
up -dasosan recreate; rolling uchun K8s Deployment (22-bob) yoki bir nechta replica + nginx upstream kerak.
Production deploy checklist¶
Birinchi marta yoki har jiddiy deploydan oldin shu ro'yxatdan o'ting. Ko'p punktlar keyingi qismlarga (monitoring, backup) ko'prik:
- Env / secret β barcha maxfiy qiymatlar serverdagi
.env(yoki secret) da, git'da emas.chmod 600 .env.docker compose configbilan o'zgaruvchilar to'g'ri o'qilganini tekshiring. - Backup β ma'lumotlar bazasi (named volume) muntazam zaxiralanyaptimi?
pg_dump+ offsite (boshqa joyga nusxa). Volume yo'qolsa ma'lumot ham yo'qoladi β bu eng katta xavf. (26-bobda chuqur.) - Healthcheck β har servisda
healthcheckbor;webda/healthendpoint;depends_on: condition: service_healthy. - Log β
docker compose logsishlayaptimi? Loglar markazlashtirilganmi yoki hech bo'lmasajournalctl/fayl orqali ko'rinadimi? (26-bob.) - Monitoring β server va ilova metrikalari (CPU, RAM, javob vaqti, xatolar) kuzatilyaptimi? (25-bob: Prometheus + Grafana.)
- HTTPS β sertifikat amaldami, auto-renew sozlanganmi, HTTPβHTTPS yo'naltirish ishlayaptimi?
- Rollback rejasi β yangi versiya buzilsa, oldingi versiyaga qanday qaytasiz? Image tag bilan:
# Yangi versiya buzildi -> oldingi tag'ga qayt (14-bobdagi semantik tag'lar)
docker compose pull # yoki aniq tag: image: ghcr.io/.../vazifalar-api:1.4.2
docker compose up -d web
β οΈ
latesttag'iga ishonmang. Production'dalatesto'rniga aniq versiya tag'i (:1.5.0) ishlating (14-bob). Aks holda "oldingi versiyaga qayt" deganda qaysi image ekanini bilmaysiz va rollback imkonsiz bo'ladi.
π Bu checklist β production'ning "minimal javobgarligi". web + db ni up -d qilib qo'yib ketish deploy emas; backup, monitoring, rollback rejasi bilan birga ishonchli deploy bo'ladi. Keyingi qismlar (V: Kubernetes, VI: monitoring/backup/IaC) shu ro'yxatni mustahkamlaydi.
Yakun¶
IV qismni yakunladik: namuna "vazifalar" ilovasini noldan production'ga chiqardik. Bitta compose.yaml da web + postgres + redis + nginx ni restart: unless-stopped, depends_on + healthcheck bilan birlashtirdik; maxfiy ma'lumotlarni serverdagi .env da (kodda emas) sakladik; domen + HTTPS ni (DNS A record, Certbot webroot, auto-renew) qo'shdik; serverga deploy oqimini (git pull / docker compose pull β up -d β healthcheck kut) va zero-downtime asoslarini (up -d --no-deps, rolling vs recreate, nginx upstream replica) ko'rdik; va production deploy checklist'ini chiqardik.
Endi sizda real, takrorlanuvchi production deploy bor. Lekin bitta serverda Compose'ning chegaralari bor: avtomatik rolling update yo'q, bir nechta serverga (klaster) tarqatish qiyin, replica'larni o'zi boshqarmaydi, biror konteyner butun serverni "olib ketsa" β zaxira yo'q. V qismda aynan shu muammolarni hal qiladigan vositaga β Kubernetesga o'tamiz. Keyingi 21-bobda Kubernetes nima uchun kerakligini va lokal klaster (minikube/kind) bilan birinchi qadamni ko'ramiz.
20-bob mashqlari¶
Oson¶
- To'liq production stack qaysi to'rt servisdan iborat? Har birining vazifasini bir jumlada ayting.
compose.yamlda nega faqatnginxdaports:bor,web/db/cacheda yo'q? Bu qanday xavfsizlik foydasi beradi?- Maxfiy ma'lumot (DB paroli) qayerda saqlanadi va qayerda saqlanmasligi kerak?
compose.yamlda nima yoziladi? docker compose up -dvadocker compose pullorasidagi farq nima? Production'da qaysi biri afzal va nega?- Nima uchun
version: "3.8"nicompose.yamlga yozmaslik kerak?
O'rta¶
depends_onning oddiy varianti vacondition: service_healthyvarianti orasidagi farqni tushuntiring. Negawebuchun ikkinchisi muhim?- Nginx config'da
proxy_pass http://web:3000da nega127.0.0.1emas,webyoziladi? (11 va 17-boblarga tayaning.) - Deploy paytida "zero-downtime" ni ta'minlash uchun
up -d --no-deps --build webbuyrug'i nima qiladi?--no-depsnimani anglatadi? - Let's Encrypt sertifikati necha kun amal qiladi va nega auto-renew kerak? Yangilashni qanday avtomatlashtirasiz?
- Rollback nima va u nega
latesttag bilan emas, aniq versiya tag bilan ishlaydi?
Qiyin¶
- To'liq production
compose.yamlyozing:web(GHCR image,restart: unless-stopped,/healthhealthcheck,dbvacachesog'lom bo'lgandan keyin ishga tushadigan),db(postgres:17-alpine, named volume,pg_isreadyhealthcheck),cache(redis:7-alpine), vanginx(80/443, config volume bilan). DB parolini.envo'zgaruvchisi bilan bering. So'ngdocker compose configbilan tekshirish buyrug'ini yozing. - Namuna ilova oldidagi
nginx/app.confni yozing: HTTP (80)'da ACME challenge yo'li + HTTPS'ga yo'naltirish, HTTPS (443)'da TLS sertifikat vaweb:3000ga proxy (zamonaviyhttp2 on;sintaksisi bilan,X-Forwarded-*headerlar bilan). Config'ni qanday tekshirasiz? - To'liq deploy ssenariysi yozing: yangi versiyani GHCR'dan tortib chiqarish ketma-ketligi (SSH β pull β up β healthcheck kut), va agar yangi versiya buzilsa rollback qadamlari. Production deploy checklist'idan kamida 5 punktni sanang.
Yechim β 11
services:
web:
image: ghcr.io/foydalanuvchi/vazifalar-api:1.5.0
restart: unless-stopped
environment:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/vazifalar
REDIS_URL: redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_healthy
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health',r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))"]
interval: 10s
timeout: 3s
retries: 5
start_period: 10s
db:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: vazifalar
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d vazifalar"]
interval: 10s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
restart: unless-stopped
nginx:
image: nginx:1.27-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/app.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
web:
condition: service_healthy
volumes:
db-data:
Tekshirish:
version: yo'q (Compose v2); maxfiy parol faqat ${DB_PASSWORD} orqali (.env da); db va cache da ports: yo'q (ichki); web aniq versiya tag bilan (1.5.0, latest emas) β rollback uchun.
Yechim β 12
nginx/app.conf:
upstream vazifalar_backend {
server web:3000;
}
server {
listen 80;
server_name vazifalar.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
http2 on;
server_name vazifalar.example.com;
ssl_certificate /etc/letsencrypt/live/vazifalar.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/vazifalar.example.com/privkey.pem;
location / {
proxy_pass http://vazifalar_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;
}
}
Tekshirish:
# Ishlab turgan stack'da:
docker compose exec nginx nginx -t
# Yoki alohida (config va sertifikatni mount qilib):
docker run --rm -v "$PWD/nginx/app.conf:/etc/nginx/conf.d/default.conf:ro" \
nginx:1.27-alpine nginx -t
http2 on; alohida qator (eski listen 443 ssl http2; emas); proxy_pass servis nomiga (web, ichki DNS); X-Forwarded-Proto $scheme β ilova so'rov HTTPS ekanini biladi.
Yechim β 13
Deploy ketma-ketligi (GHCR'dan tayyor image):
ssh deploy@203.0.113.10
cd /opt/vazifalar-api
docker compose pull # yangi image'ni GHCR'dan tort
docker compose up -d # konteynerni yangi image bilan almashtir
docker compose ps # web "healthy" bo'lishini kut
docker compose logs -f web # loglarda xato yo'qligini ko'r
curl -fsS https://vazifalar.example.com/health # tashqaridan tekshir
Rollback (yangi versiya buzildi):
# compose.yaml'da tag'ni oldingi ishlagan versiyaga qaytar, masalan:
# image: ghcr.io/foydalanuvchi/vazifalar-api:1.4.2
docker compose pull web
docker compose up -d web # eski (ishlagan) image bilan almashtir
docker compose ps # yana healthy ekanini tekshir
Checklist (5+ punkt):
- Env/secret β
.envserverda,chmod 600, git'da yo'q. - Backup β DB volume muntazam zaxiralanadi (
pg_dump+ offsite). - Healthcheck β har servisda healthcheck,
webda/health. - Log β
docker compose logsishlaydi, loglar kuzatiladi. - Monitoring β CPU/RAM/javob vaqti/xatolar kuzatiladi (25-bob).
- HTTPS β sertifikat amalda, auto-renew sozlangan, HTTPβHTTPS yo'naltirish bor.
- Rollback rejasi β aniq versiya tag bilan oldingi versiyaga qaytish yo'li tayyor.
latest o'rniga aniq tag (1.4.2) ishlatish rollback'ni mumkin qiladi: "oldingi versiya" qaysi image ekani aniq.
β¬ οΈ Oldingi: 19 β systemd va process boshqaruvi Β· π README Β· Keyingi: 21 β Nega Kubernetes: arxitektura va lokal klaster β‘οΈ