depends_on va healthcheck — ishga tushish tartibi
Muammodan boshlaylik
services:
api:
build: .
depends_on:
- baza
baza:
image: mysql:8.4
docker compose up — va API yiqiladi:
api-1 | Error: connect ECONNREFUSED 172.18.0.2:3306
api-1 exited with code 1
depends_on bor-ku! Nega API baza tayyor bo'lmasdan ishga tushdi?
depends_on aslida nima qiladi
Oddiy depends_on — faqat ishga tushish tartibini belgilaydi: avval baza konteyneri ishga tushadi, keyin api. Lekin:
0.0s baza konteyneri ishga tushdi ← depends_on shuni kutadi
0.1s api konteyneri ishga tushdi ← API bazaga ulanmoqchi...
... MySQL init: fayllar, init skriptlar (10-30 soniya)
25s MySQL ulanishlarni qabul qilishga TAYYOR
Konteyner ishga tushgani ≠ ilova tayyor (22-dars).
Yechim: healthcheck + condition
1. Baza uchun sog'liqni tekshirish:
services:
baza:
image: mysql:8.4
environment:
MYSQL_ROOT_PASSWORD: root123
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "--silent"]
interval: 5s
timeout: 5s
retries: 20
start_period: 30s
| Parametr | Ma'nosi |
|---|---|
test |
Tekshiruv buyrug'i; 0 — sog'lom, boshqa — yo'q |
interval |
Qanchalik tez-tez |
timeout |
Bitta tekshiruv uchun maksimal vaqt |
retries |
Necha marta ketma-ket muvaffaqiyatsiz — unhealthy |
start_period |
Boshlang'ich vaqt — bu davrdagi muvaffaqiyatsizliklar hisoblanmaydi |
2. API — sog'lom bo'lishini kutsin:
api:
build: .
depends_on:
baza:
condition: service_healthy
Endi:
✔ Container dokon-baza-1 Healthy ← 25 soniya kutildi
✔ Container dokon-api-1 Started
condition turlari
condition |
Kutadi |
|---|---|
service_started |
Konteyner ishga tushishini (oddiy depends_on kabi) |
service_healthy |
healthcheck sog'lom deyishini |
service_completed_successfully |
Konteyner 0 kodi bilan tugashini — migratsiyalar uchun |
Har xil xizmatlar uchun healthcheck
# PostgreSQL
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
retries: 10
# Redis
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
# MongoDB
healthcheck:
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping')"]
# O'z API ingiz (HTTP endpoint)
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
interval: 15s
start_period: 10s
CMD— buyruq to'g'ridan-to'g'ri;CMD-SHELL— shell orqali (o'zgaruvchilar,||kabi)$— Compose dagi$ni qochirish:${POSTGRES_USER}— konteyner ichidagi o'zgaruvchi, Compose.envniki emas
Healthcheck buyrug'i image ichida mavjud bo'lishi kerak: Alpine da curl yo'q — wget; distroless da hech narsa yo'q — ilovaning o'zi bilan (13-dars).
Migratsiyalarni bir marta bajarish
services:
migrate:
build: .
command: ["npx", "prisma", "migrate", "deploy"]
depends_on:
baza:
condition: service_healthy
restart: "no"
api:
build: .
depends_on:
migrate:
condition: service_completed_successfully
Tartib: baza sog'lom → migratsiyalar bajariladi va tugaydi → API ishga tushadi. Migratsiya xato bersa — API umuman ishga tushmaydi.
Ilova ham chidamli bo'lsin
depends_on — faqat ishga tushish paytida. Keyin baza qayta ishga tushsa yoki tarmoq uzilsa — Compose hech narsa qilmaydi. Ilovaning o'zi:
- Baza ulanishini qayta urinish bilan qilsin (ko'p ORM va pool lar buni qiladi)
- Ulanish uzilsa — yiqilmasdan qayta ulansin
restart: unless-stopped— yiqilsa ham qayta ko'tarilsin
depends_on + healthcheck — qulaylik; ilovaning chidamliligi — zarurat.
Holatni ko'rish
docker compose ps
NAME SERVICE STATUS PORTS
dokon-api-1 api Up 2 minutes (healthy) 0.0.0.0:3000->3000/tcp
dokon-baza-1 baza Up 3 minutes (healthy) 3306/tcp
docker inspect --format '{{json .State.Health}}' dokon-baza-1
Oxirgi tekshiruvlar natijasi va xato matni — healthcheck nega muvaffaqiyatsiz ekanini ko'rish uchun.
Nima uchun shunday?
Nima uchun depends_on standart holatda faqat konteyner ishga tushishini kutadi, ilova tayyorligini emas?
Chunki Docker ilova qachon "tayyor" ekanini bilmaydi. MySQL uchun — ulanish qabul qilganda; API uchun — /health 200 qaytarganda; worker uchun — navbatga ulanganda. Har bir xizmat uchun "tayyorlik" ta'rifi boshqacha. Docker taxmin qilmaydi — siz healthcheck orqali aniq aytasiz. Taxmin qilingan "tayyorlik" ba'zan ishlardi, ba'zan yo'q — va bunday xatolar eng qiyin topiladiganlari.
Xulosa
Eslab qoling:
- Oddiy
depends_on— faqat konteyner tartibi, tayyorlik emas healthcheck+condition: service_healthy— haqiqiy kutish- MySQL:
mysqladmin ping; PostgreSQL:pg_isready; Redis:redis-cli ping; API:/health CMDvaCMD-SHELL;$— konteyner o'zgaruvchisiservice_completed_successfully— migratsiyalar oldin- Ilovaning o'zi ham qayta ulanishi kerak;
restart: unless-stopped
Keyingi dars
29-dars: Compose da o'zgaruvchilar — .env, env_file, secrets