IlmHamroh
Python kursi/Infratuzilma3/14-dars18 daqiqa
Mundarija (22)

28.3-dars: Docker Compose

28-QISM — INFRATUZILMA · 3-dars


1. Kirish va motivatsiya

Haqiqiy ilova bir konteynerdan iborat emas: veb-dastur, ma'lumotlar bazasi (PostgreSQL), kesh (Redis), navbat (RabbitMQ) — har biri alohida konteyner. Ularni qo'lda ishga tushirish og'riqli: har biriga docker run (port, volume, tarmoq, muhit — uzun buyruqlar), to'g'ri tartibda, to'g'ri tarmoqda. Bir konteynerni unutsangiz — ilova ishlamaydi. Docker Compose bu murakkablikni hal qiladi: barcha konteynerlarni (servislar) bitta YAML fayl da ta'riflaysiz, keyin bitta buyruq — docker compose up — hammasini to'g'ri tartibda, to'g'ri tarmoqda ishga tushiradi.

Docker Compose — ko'p konteynerli ilovalarni ta'riflash va boshqarish vositasi: docker-compose.yml (YAML fayl — barcha servislar, ularning sozlamalari), service (har konteyner — image, port, volume, muhit), depends_on (bog'liqlik tartibi), networks (servislar aloqasi), volumes (doimiy saqlash). Bir buyruq (docker compose up) — barcha servislarni ishga tushiradi; docker compose down — to'xtatadi. Compose — rivojlanish muhitini bir buyruqda tayyorlaydi (dastur + baza + kesh). Bu deklarativ (nima kerakligini ta'riflaysiz, qanday emas). Docker Compose — ko'p konteynerni bir joyda boshqarish. YAML — ilovaning to'liq tavsifi.

Real vaziyat. Bir loyihada yangi dasturchi muhitni sozlash uchun 8 ta terminal ochib, har xil docker run buyruqlarini to'g'ri tartibda kiritishga urinardi (baza avval, keyin dastur) — tez-tez xato qilardi. docker-compose.yml yozildi: 4 servis (veb, PostgreSQL, Redis, worker) ta'riflandi, bog'liqliklar (depends_on), tarmoq, volume. Endi docker compose up — hammasi 10 soniyada ishga tushdi (to'g'ri tartibda). Yangi dasturchi bir buyruqda boshladi. Compose — muhitni bir buyruqqa jamladi.

Bu darsda Docker Compose ni o'rganamiz.

Bu darsda:

  • Docker Compose nima
  • docker-compose.yml tuzilishi
  • Servislar (service)
  • Bog'liqlik va tartib (depends_on)
  • Tarmoq va volume
  • Compose buyruqlari (up, down, logs)
  • Compose qayerda foydali
  • Amaliy: compose modeli

ℹ Compose OS vositasi; misollar Python bilan compose tuzilishi/mantiqini modellashtiradi (deterministik).


2. Nazariya — chuqur tushuntirish

2.1. Docker Compose nima

Ko'p konteynerni bir joyda:

Qo'lda: har konteynerga docker run (uzun, tartibli)
   docker run baza... docker run kesh... docker run dastur...

Compose: docker-compose.yml (barcha servislar)
   docker compose up → hammasi (to'g'ri tartibda)

Docker Compose — ko'p konteynerli ilovalarni bitta YAML fayl da ta'riflab, bir buyruq bilan boshqarish vositasi: barcha servislar (dastur, baza, kesh), ularning sozlamalari, bog'liqliklari bir joyda. Sabab: haqiqiy ilova ko'p konteyner (dastur + baza + kesh + navbat) — ularni qo'lda ishga tushirish (har biriga docker run, to'g'ri tartib, tarmoq) og'riqli va xatoga moyil; Compose buni deklarativ qiladi (ta'rifla, bir buyruq). Compose — rivojlanish muhitini bir buyruqda. Ko'p konteyner — bir tavsif.

2.2. docker-compose.yml tuzilishi

Servislar tavsifi:

yaml
services:
  veb:
    build: .              # Dockerfile'dan qur
    ports:
      - "8000:8000"
    depends_on:
      - baza
  baza:
    image: postgres:16    # tayyor image
    environment:
      POSTGRES_PASSWORD: sir
    volumes:
      - db-data:/var/lib/postgresql/data
volumes:
  db-data:

docker-compose.yml — YAML formatidagi fayl, ilovaning to'liq tavsifi: services (har konteyner — veb, baza, kesh), har servis uchun: build (Dockerfile'dan qurish) yoki image (tayyor image), ports (port xaritalash), environment (muhit o'zgaruvchilari), volumes (doimiy saqlash), depends_on (bog'liqlik). Yuqori darajada: services, volumes, networks. YAML — o'qiladigan, deklarativ (nima kerak, qanday emas). Bu Dockerfile (28.2 — bir image) dan farqli — Compose butun ilovani (ko'p konteyner) ta'riflaydi. YAML — ilova tavsifi. Deklarativ — nima kerakligi.

2.3. Servislar (service)

Har servis bir konteyner:

yaml
services:
  veb:              # servis nomi
    build: .        # yoki image: myapp:v1
    ports:
      - "8000:8000" # host:container
    environment:
      - DEBUG=false
  kesh:
    image: redis:7

Servis (service) — Compose'dagi bir konteyner ta'rifi: nomi (veb, baza, kesh — tarmoqda shu nom bilan chaqiriladi), build (Dockerfile'dan) yoki image (tayyor), ports ("8000:8000" — host:container), environment (muhit o'zgaruvchilari), volumes (saqlash), command (ishga tushirish buyrug'ini bekor qilish). Har servis mustaqil konteyner, lekin ular bir ilova (birga ishlaydi). Servislar bir-birini nomi bilan chaqiradi (baza:5432 — Compose ichki DNS). Servis — ilovaning bir qismi (konteyner). Nom — tarmoqdagi manzil.

2.4. Bog'liqlik va tartib (depends_on)

Ishga tushirish tartibi:

yaml
services:
  veb:
    depends_on:
      - baza        # baza avval ishga tushadi
      - kesh
  baza:
    image: postgres:16
  kesh:
    image: redis:7
# tartib: baza, kesh → keyin veb

depends_on — servislar orasidagi bog'liqlik tartibi: veb bazaga bog'liq (depends_on: baza) — Compose bazani avval ishga tushiradi, keyin veb. Sabab: dastur bazasiz ishlay olmaydi (ulanish kerak) — to'g'ri tartib muhim. Ehtiyot: depends_on faqat ishga tushish tartibini kafolatlaydi (konteyner boshlandi), tayyorlikni emas (baza qabul qilishga tayyormi?) — buning uchun healthcheck (sog'liq tekshiruvi) yoki dasturda qayta urinish 27.12-bob. Bog'liqlik — kim kimni kutadi. Tartib — to'g'ri ishga tushish (lekin tayyorlik alohida). depends_on — boshlash tartibi.

2.5. Tarmoq va volume

Aloqa va saqlash:

yaml
services:
  veb:
    volumes:
      - ./kod:/app    # host papka → container
  baza:
    volumes:
      - db-data:/var/lib/postgresql/data   # nomli volume
volumes:
  db-data:            # doimiy saqlash
# servislar bir tarmoqda (avtomatik) — nomi bilan chaqiradi

Tarmoq va volume: Tarmoq — Compose servislarni avtomatik bir tarmoqqa joylaydi, ular bir-birini nomi bilan chaqiradi (veb → baza:5432 — DNS orqali, IP kerak emas). Volume — doimiy saqlash: bind mount (./kod:/app — host papka konteynerga, rivojlanishda kod o'zgarishlari darhol), nomli volume (db-data — Docker boshqaradi, baza ma'lumoti — konteyner o'chsa qoladi). Sabab: konteyner o'tkinchi 28.1-bob — baza ma'lumoti volume'da (yo'qolmasin), kod bind mount (tez rivojlanish). Tarmoq — servislar aloqasi, volume — doimiy saqlash. Aloqa va saqlash — birga ishlash.

2.6. Compose buyruqlari (up, down, logs)

bash
docker compose up          # barcha servislar (old planda)
docker compose up -d       # fonda (detached)
docker compose down        # to'xtatish va o'chirish
docker compose ps          # holat
docker compose logs veb    # bir servis loglari
docker compose build       # imagelarni qayta qurish
docker compose exec veb bash   # servis ichiga kirish

Compose buyruqlari: up — barcha servislarni ishga tushirish (-d — fonda), tarmoq/volume yaratadi; down — to'xtatish va tozalash (konteyner, tarmoq o'chadi — volume ixtiyoriy); ps — holat (qaysi servis ishlayapti); logs — chiqishni ko'rish (barcha yoki bir servis); build — imagelarni qurish; exec — servis ichiga kirish; restart — qayta ishga tushirish. Bir buyruq butun ilovaga ta'sir qiladi (barcha servis). Compose buyruqlari — ilovani boshqarish (butun sifatida). up/down — ilovani yoqish/o'chirish.

2.7. Compose qayerda foydali

Docker Compose foydali: rivojlanish muhiti (asosiy foydalanish — dastur + baza + kesh bir buyruqda, "mening mashinamda" muammosiz — yangi dasturchi tez boshlaydi); test muhiti (CI'da — 28.7 — izchil test uchun servislar); kichik deploy (bir serverda ko'p konteyner — kichik loyiha). Kamroq mos: katta ishlab chiqarish (ko'p server, avtomatik miqyoslash — Kubernetes 28.5 kerak). Compose — bir mashinada ko'p konteyner (dev, kichik prod); Kubernetes — ko'p mashina (katta prod). Bu Docker (28.1-2) ustiga quriladi (Compose — ko'p Dockerfile/image). Compose — rivojlanish va kichik deploy uchun. Bir mashina, ko'p konteyner.

2.8. Compose — deklarativ muhit

Docker Compose deklarativ yondashuvni ko'rsatadi: siz muhitni qanday qurishni (buyruqlar ketma-ketligi) emas, nima kerakligini (servislar, ularning holati) ta'riflaysiz — Compose buni amalga oshiradi. Bu Dockerfile (28.2 — muhit kodi) ni ilova darajasiga ko'taradi (butun ilova kodi). docker-compose.yml git'da (versiyalangan, jamoa bir xil, hujjat — ilova nimalardan iborat). Bu infrastructure as code 28.14-bob ning boshlanishi, Kubernetes (28.5 — deklarativ orkestratsiya) ga ko'prik. Deklarativ — nima kerakligini ayt (imperativ — qanday qilishni emas). Compose — ilovani deklarativ ta'riflash. YAML — ilovaning yagona haqiqati.


3. Tez ma'lumotnoma

yaml
# docker-compose.yml
services:
  veb:
    build: .                  # Dockerfile'dan
    ports:
      - "8000:8000"           # host:container
    environment:
      - DEBUG=false
    depends_on:
      - baza                  # tartib
    volumes:
      - ./kod:/app            # bind mount (rivojlanish)
  baza:
    image: postgres:16        # tayyor image
    environment:
      POSTGRES_PASSWORD: sir
    volumes:
      - db-data:/var/lib/postgresql/data   # nomli volume
  kesh:
    image: redis:7
volumes:
  db-data:                    # doimiy saqlash

# BUYRUQLAR:
# docker compose up -d       # ishga tushirish (fonda)
# docker compose down        # to'xtatish
# docker compose ps          # holat
# docker compose logs veb    # loglar
# docker compose exec veb bash   # ichiga kirish

# servislar nomi bilan aloqa: veb → baza:5432 (DNS)

Docker Compose xulosasi

Compose — ko'p konteynerni bir YAML'da (docker-compose.yml)
services — har konteyner (build/image, ports, env, volumes)
depends_on — tartib (tayyorlik emas — healthcheck)
Tarmoq (avtomatik, nom bilan aloqa) · Volume (doimiy)
up/down — bir buyruq · deklarativ (nima kerak)

4. Batafsil misollar

Compose OS vositasi; misollar Python bilan compose tuzilishi/mantiqini modellashtiradi.

Misol 1 — Compose tuzilishi (servislar)

python
"""Compose tuzilishi: servislar va ularning sozlamalari (dict modeli)."""


def compose_tahlil(compose: dict) -> dict:
    servislar = compose.get("services", {})
    natija = {}
    for nom, sozlama in servislar.items():
        natija[nom] = {
            "manba": "build" if "build" in sozlama else sozlama.get("image", "?"),
            "portlar": sozlama.get("ports", []),
            "bogliqliklar": sozlama.get("depends_on", []),
        }
    return natija


def main() -> None:
    compose = {
        "services": {
            "veb": {"build": ".", "ports": ["8000:8000"], "depends_on": ["baza", "kesh"]},
            "baza": {"image": "postgres:16"},
            "kesh": {"image": "redis:7"},
        },
        "volumes": {"db-data": None},
    }

    tahlil = compose_tahlil(compose)

    print("=== 1. Servislar soni ===")
    print(f"  {len(tahlil)} servis: {list(tahlil)}")

    print("\n=== 2. Har servis manbasi ===")
    for nom, info in tahlil.items():
        print(f"  {nom}: {info['manba']}")

    print("\n=== 3. Portlar ===")
    for nom, info in tahlil.items():
        if info["portlar"]:
            print(f"  {nom}: {info['portlar']}")

    print("\n=== 4. Bog'liqliklar ===")
    print(f"  veb bog'liq: {tahlil['veb']['bogliqliklar']}")
    print("  ⭐ Compose — servislar (bir ilova)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Servislar soni ===
  3 servis: ['veb', 'baza', 'kesh']

=== 2. Har servis manbasi ===
  veb: build
  baza: postgres:16
  kesh: redis:7

=== 3. Portlar ===
  veb: ['8000:8000']

=== 4. Bog'liqliklar ===
  veb bog'liq: ['baza', 'kesh']
  ⭐ Compose — servislar (bir ilova)

Nima ko'rsatdi: 2.1, 2.2, 2.3-bo'limlar.

Misol 2 — Ishga tushirish tartibi (depends_on)

python
"""depends_on: bog'liqliklarga qarab to'g'ri ishga tushirish tartibi (topologik)."""


def ishga_tushirish_tartibi(servislar: dict) -> list:
    """Bog'liqliklarga qarab tartib (bog'liq bo'lganlar avval)."""
    tartib: list = []

    def qosh(nom: str) -> None:
        if nom in tartib:
            return
        # avval bog'liqliklarni ishga tushir (rekursiv)
        for bogliq in servislar.get(nom, {}).get("depends_on", []):
            qosh(bogliq)
        tartib.append(nom)

    for nom in servislar:
        qosh(nom)
    return tartib


def main() -> None:
    servislar = {
        "veb": {"depends_on": ["baza", "kesh"]},
        "worker": {"depends_on": ["baza", "navbat"]},
        "baza": {},
        "kesh": {},
        "navbat": {},
    }

    tartib = ishga_tushirish_tartibi(servislar)

    print("=== 1. Servislar ===")
    print(f"  {list(servislar)}")

    print("\n=== 2. Ishga tushirish tartibi ===")
    for i, nom in enumerate(tartib, 1):
        print(f"  {i}. {nom}")

    print("\n=== 3. Bog'liqliklar avval ===")
    print(f"  baza veb'dan oldin: {tartib.index('baza') < tartib.index('veb')}")
    print(f"  kesh veb'dan oldin: {tartib.index('kesh') < tartib.index('veb')}")

    print("\n=== 4. Eslatma ===")
    print("  depends_on — ishga tushish tartibi (boshlandi)")
    print("  tayyorlik emas (healthcheck kerak)")
    print("  ⭐ depends_on — to'g'ri tartib")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Servislar ===
  ['veb', 'worker', 'baza', 'kesh', 'navbat']

=== 2. Ishga tushirish tartibi ===
  1. baza
  2. kesh
  3. veb
  4. navbat
  5. worker

=== 3. Bog'liqliklar avval ===
  baza veb'dan oldin: True
  kesh veb'dan oldin: True

=== 4. Eslatma ===
  depends_on — ishga tushish tartibi (boshlandi)
  tayyorlik emas (healthcheck kerak)
  ⭐ depends_on — to'g'ri tartib

Nima ko'rsatdi: 2.4-bo'lim.

Misol 3 — Servislararo aloqa (nom bilan)

python
"""Servis aloqasi: servislar bir tarmoqda, nomi bilan chaqiradi (DNS)."""


class ComposeTarmoq:
    def __init__(self) -> None:
        self.servislar: dict = {}   # nom → port

    def qosh(self, nom: str, port: int) -> None:
        self.servislar[nom] = port

    def ulanish_manzili(self, servis_nomi: str) -> str:
        # servis nomi bilan (IP emas) — Compose DNS
        if servis_nomi not in self.servislar:
            return f"Xato: {servis_nomi} topilmadi"
        return f"{servis_nomi}:{self.servislar[servis_nomi]}"


def main() -> None:
    tarmoq = ComposeTarmoq()
    tarmoq.qosh("baza", 5432)
    tarmoq.qosh("kesh", 6379)
    tarmoq.qosh("navbat", 5672)

    print("=== 1. Tarmoqdagi servislar ===")
    print(f"  {list(tarmoq.servislar)}")

    print("\n=== 2. Veb → baza ulanishi (nom bilan) ===")
    print(f"  {tarmoq.ulanish_manzili('baza')}")
    print("  IP emas, servis nomi (Compose DNS)")

    print("\n=== 3. Boshqa ulanishlar ===")
    print(f"  kesh: {tarmoq.ulanish_manzili('kesh')}")
    print(f"  navbat: {tarmoq.ulanish_manzili('navbat')}")

    print("\n=== 4. Yo'q servis ===")
    print(f"  {tarmoq.ulanish_manzili('mongo')}")
    print("  servislar nomi bilan aloqa (bir tarmoq)")
    print("  ⭐ Servislar — nom bilan chaqiradi (DNS)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Tarmoqdagi servislar ===
  ['baza', 'kesh', 'navbat']

=== 2. Veb → baza ulanishi (nom bilan) ===
  baza:5432
  IP emas, servis nomi (Compose DNS)

=== 3. Boshqa ulanishlar ===
  kesh: kesh:6379
  navbat: navbat:5672

=== 4. Yo'q servis ===
  Xato: mongo topilmadi
  servislar nomi bilan aloqa (bir tarmoq)
  ⭐ Servislar — nom bilan chaqiradi (DNS)

Nima ko'rsatdi: 2.5-bo'lim.

Misol 4 — Compose hayotiy sikli (up, down)

python
"""Compose buyruqlari: up (barcha servis), down (to'xtatish) — butun ilova."""


class Compose:
    def __init__(self, servislar: list) -> None:
        self.servislar = servislar
        self.holat: dict = {s: "stopped" for s in servislar}

    def up(self) -> list:
        natija = []
        for s in self.servislar:
            self.holat[s] = "running"
            natija.append(f"{s} ishga tushdi")
        return natija

    def down(self) -> list:
        natija = []
        for s in self.servislar:
            self.holat[s] = "stopped"
            natija.append(f"{s} to'xtadi")
        return natija

    def ps(self) -> dict:
        return dict(self.holat)


def main() -> None:
    compose = Compose(["veb", "baza", "kesh"])

    print("=== 1. Boshlang'ich holat ===")
    print(f"  {compose.ps()}")

    print("\n=== 2. docker compose up ===")
    for satr in compose.up():
        print(f"  {satr}")

    print("\n=== 3. Holat (ps) ===")
    print(f"  {compose.ps()}")

    print("\n=== 4. docker compose down ===")
    for satr in compose.down():
        print(f"  {satr}")
    print(f"  yakuniy holat: {compose.ps()}")
    print("  bir buyruq → butun ilova (barcha servis)")
    print("  ⭐ Compose — ilovani boshqarish (butun)")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Boshlang'ich holat ===
  {'veb': 'stopped', 'baza': 'stopped', 'kesh': 'stopped'}

=== 2. docker compose up ===
  veb ishga tushdi
  baza ishga tushdi
  kesh ishga tushdi

=== 3. Holat (ps) ===
  {'veb': 'running', 'baza': 'running', 'kesh': 'running'}

=== 4. docker compose down ===
  veb to'xtadi
  baza to'xtadi
  kesh to'xtadi
  yakuniy holat: {'veb': 'stopped', 'baza': 'stopped', 'kesh': 'stopped'}
  bir buyruq → butun ilova (barcha servis)
  ⭐ Compose — ilovani boshqarish (butun)

Nima ko'rsatdi: 2.6-bo'lim.


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

Noto'g'ri fikr To'g'risi
"Har konteyner qo'lda run" Compose (bir buyruq)
"depends_on tayyorlikni kafolatlaydi" Faqat tartib (healthcheck kerak)
"Servislar IP bilan aloqa" Nom bilan (Compose DNS)
"Compose = Kubernetes" Compose bir mashina, K8s ko'p
"Ma'lumot container ichida" Volume (doimiy)
"Compose faqat prod" Asosan rivojlanish (dev)
"YAML imperativ" Deklarativ (nima kerak)
"Bir yml = bir konteyner" Bir yml = butun ilova

6. Keng tarqalgan xatolar va yechimlari

1. depends_on tayyorlik deb o'ylash

yaml
depends_on: [baza]   # baza tayyor emas (faqat boshlandi)  # ⚠️
# healthcheck yoki dasturda qayta urinish                  # ✅

2. Ma'lumotni volume'siz baza

yaml
baza:
  image: postgres   # ma'lumot yo'qoladi (down'da)          # ⚠️
  volumes: [db-data:/var/lib/postgresql/data]               # ✅

3. Sirlarni yml'ga yozish

yaml
environment:
  PAROL: secret123   # yml git'da (sir!)                     # ⚠️
  PAROL: ${DB_PAROL}   # .env dan (git'siz)                  # ✅

4. Servisni IP bilan chaqirish

python
ulanish("172.18.0.2")   # IP o'zgaradi                       # ⚠️
ulanish("baza:5432")    # nom (barqaror)                     # ✅

5. Port to'qnashuvi (bir host port)

yaml
veb1: ports: ["8000:8000"]
veb2: ports: ["8000:8000"]   # to'qnashuv                    # ⚠️
veb2: ports: ["8001:8000"]                                   # ✅

6. down -v (volume o'chirish) ehtiyotsizligi

bash
docker compose down -v   # volume ham o'chadi (ma'lumot!)    # ⚠️
docker compose down       # volume qoladi                     # ✅

7. Compose'ni katta prod uchun

yaml
# 50 konteyner, ko'p server Compose bilan                    # ⚠️
# Kubernetes (orkestratsiya)                                  # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 28.1-2-dars (o'tilgan): Docker, Dockerfile — asos
  • 28.5-dars: Kubernetes — katta orkestratsiya
  • 28.7-dars: CI — test muhiti (compose)
  • 27.9-dars (o'tilgan): Mikroservis — ko'p servis
  • 23-qism (o'tilgan): Baza — compose'da servis

8. Eng yaxshi amaliyotlar

  1. Bir yml — butun ilova (barcha servis).

  2. depends_on + healthcheck (tayyorlik).

  3. Ma'lumot — nomli volume (doimiy).

  4. Sirlar — .env dan (yml'da emas).

  5. Servislar nom bilan aloqa (IP emas).

  6. Port to'qnashuvidan saqlan.

  7. down -v ehtiyot (volume).

  8. Compose — dev/kichik; katta — Kubernetes.


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # Docker Compose nima?
2.  # docker-compose.yml nima?
3.  # service nima?
4.  # build vs image?
5.  # depends_on nima?
6.  # depends_on tayyorlikni kafolatlaydimi?
7.  # servislar qanday aloqa?
8.  # volume nima uchun?
9.  # docker compose up?
10. # docker compose down?
11. # Compose vs Kubernetes?
12. # deklarativ nima?
Javoblar
  1. Ko'p konteynerni bir YAML'da boshqarish
  2. Ilova tavsifi (servislar)
  3. Bir konteyner ta'rifi
  4. build Dockerfile'dan, image tayyor
  5. Ishga tushirish tartibi (bog'liqlik)
  6. Yo'q (faqat boshlanish, tayyorlik emas)
  7. Nomi bilan (Compose DNS)
  8. Doimiy saqlash (container o'tkinchi)
  9. Barcha servisni ishga tushirish
  10. To'xtatish va o'chirish
  11. Compose bir mashina, K8s ko'p mashina
  12. Nima kerakligini ta'riflash (qanday emas)

Vazifa 2: Xatolarni tuzating

yaml
1.  depends_on: [baza]   # tayyor deb o'ylash

2.  baza: image: postgres   # volume yo'q

3.  environment: PAROL: secret   # sir yml'da

4.  ulanish("172.18.0.2")   # IP

5.  down -v   # volume o'chirish
Javoblar
yaml
1.  + healthcheck (yoki qayta urinish)

2.  volumes: [db-data:/var/lib/postgresql/data]

3.  PAROL: ${DB_PAROL}  # .env dan

4.  ulanish("baza:5432")  # nom

5.  docker compose down  # volume qoladi

Vazifa 3: Compose

Yozing:

  1. services
  2. veb (build)
  3. baza (image)
  4. volumes

Vazifa 4: Tartib

Modellang:

  1. Servislar
  2. depends_on
  3. Tartib
  4. Bog'liq avval

Vazifa 5: Aloqa

Modellang:

  1. Servislar
  2. Nom bilan
  3. DNS
  4. Port

Vazifa 6: Hayotiy sikl

Modellang:

  1. up
  2. Holat
  3. down
  4. Butun ilova

Vazifa 7: O'ylash

Docker Compose deklarativ yondashuvni ko'rsatadi: siz muhitni qanday qurishni emas, nima kerakligini ta'riflaysiz. Nima uchun bu "deklarativ vs imperativ" farqi infratuzilmada shunchalik muhim (Kubernetes, Terraform ham deklarativ), va nega "nima kerak" ni ta'riflash "qanday qilish" ni buyurishdan ishonchliroq?

Javob

Qisqa javob: "Deklarativ vs imperativ" farqi infratuzilmada muhim, chunki: imperativ — "qanday qilish" ni qadam-baqadam buyurish (docker run baza; docker run kesh; docker run veb — aniq ketma-ketlik, buyruqlar); deklarativ — "nima kerak" ni ta'riflash (docker-compose.yml — 3 servis kerak, ular ishlashi kerak — tizim buni qanday amalga oshirishni o'zi hal qiladi). Deklarativ ishonchliroq, chunki: istalgan holat (desired state) aniq (nima bo'lishi kerak — ta'riflangan), tizim joriy holatni shu istalgan holatga keltiradi (nima yetishmasa qo'shadi, nima ortiqcha o'chiradi — "reconciliation"); imperativ esa buyruqlar ketma-ketligi (agar bir qadam allaqachon bajarilgan bo'lsa? xato bo'lsa? qayta ishga tushsa?) — holat noaniq. Masalan: deklarativ "3 konteyner ishlashi kerak" — agar 1 tasi yiqilsa, tizim qayta ishga tushiradi (istalgan holatga qaytaradi); imperativ "docker run x3" — yiqilsa hech narsa bo'lmaydi (buyruq bir marta bajarilgan). Deklarativ idempotent (26.9 — bir necha marta qo'llash bir xil natija — "up" ni qayta ishga tushirish xavfsiz, joriy holatni istalgan holatga keltiradi); imperativ takrorlash muammoli (run ikki marta — ikki konteyner?). Deklarativ o'z-o'zini tuzatadi (self-healing — istalgan holatdan chetlanishni tuzatadi — Kubernetes buni doim qiladi); imperativ statik (bir marta bajarildi, keyin nazorat yo'q). Shuning uchun infratuzilma vositalari (Compose, Kubernetes, Terraform) deklarativ: infratuzilma holat haqida (nima ishlashi kerak), harakatlar ketma-ketligi haqida emas. Muhandislik saboqlari: deklarativ — "nima" (istalgan holat), imperativ — "qanday" (qadamlar); deklarativ idempotent, o'z-o'zini tuzatadi (ishonchli); infratuzilma — holatni boshqarish (deklarativ mos); "nima kerak" barqaror (o'zgarmas maqsad), "qanday qilish" mo'rt (qadamlar buzilishi mumkin).

1. Deklarativ vs imperativ

Imperativ: "qanday qilish" (buyruqlar ketma-ketligi). Deklarativ: "nima kerak" (istalgan holat).

2. Nega deklarativ ishonchliroq

Jihat Deklarativ
Istalgan holat Aniq (ta'riflangan)
Joriy → istalgan Tizim keltiradi (reconciliation)
Yiqilsa Qayta tiklaydi (self-healing)

3. Idempotentlik

Deklarativ: qayta qo'llash xavfsiz (joriy → istalgan). Imperativ: takrorlash muammoli (run x2 — ikki konteyner?).

4. O'z-o'zini tuzatish

Deklarativ: istalgan holatdan chetlanishni tuzatadi (K8s doim). Imperativ: statik (bir marta, nazorat yo'q).

5. Muhandislik saboqlari

  1. Deklarativ "nima", imperativ "qanday"
  2. Deklarativ idempotent, self-healing
  3. Infratuzilma — holatni boshqarish
  4. "Nima kerak" barqaror, "qanday" mo'rt

6. Xulosa

  1. Imperativ — qadamlar, deklarativ — istalgan holat
  2. Deklarativ — tizim holatni keltiradi (reconciliation)
  3. Idempotent, o'z-o'zini tuzatadi (ishonchli)
  4. Infratuzilma deklarativ (holat haqida)

Nimani mustahkamlaydi: 2.2, 2.8-bo'limlar.


Xulosa

Bu darsda Docker Compose ni o'rgandik.

Eng muhim uch fikr:

  1. Docker Compose va yml tuzilishi. Docker Compose — ko'p konteynerli ilovalarni bitta YAML fayl da ta'riflab, bir buyruq bilan boshqarish: haqiqiy ilova ko'p konteyner (dastur + baza + kesh) — qo'lda ishga tushirish og'riqli, Compose buni deklarativ qiladi. docker-compose.yml — ilovaning to'liq tavsifi: services (har konteyner — build Dockerfile'dan yoki image tayyor, ports, environment, volumes), yuqorida services, volumes, networks. Servis — bir konteyner ta'rifi (nomi bilan tarmoqda chaqiriladi).

  2. Bog'liqlik, tarmoq, volume. depends_on — servislar orasidagi ishga tushirish tartibi (veb bazaga bog'liq — baza avval); lekin faqat tartibni kafolatlaydi (konteyner boshlandi), tayyorlikni emas (baza qabul qilishga tayyormi?) — healthcheck yoki qayta urinish 27.12-bob kerak. Tarmoq — servislar avtomatik bir tarmoqda, bir-birini nomi bilan chaqiradi (baza:5432 — Compose DNS, IP emas). Volume — doimiy saqlash: bind mount (./kod:/app — rivojlanish) yoki nomli volume (db-data — baza ma'lumoti, konteyner o'chsa qoladi).

  3. Buyruqlar va deklarativlik. Buyruqlar: up (barcha servis — -d fonda), down (to'xtatish, tozalash), ps (holat), logs, exec, build. Compose foydali: rivojlanish muhiti (asosiy — bir buyruqda hammasi), test (CI), kichik deploy; katta prod uchun Kubernetes (28.5 — ko'p mashina). Compose deklarativ yondashuvni ko'rsatadi: muhitni qanday qurishni emas, nima kerakligini ta'riflaysiz — bu imperativ (qadamlar)dan ishonchliroq (istalgan holat aniq, tizim joriy holatni keltiradi — reconciliation, idempotent, o'z-o'zini tuzatadi). docker-compose.yml git'da (versiyalangan, deklarativ muhit kodi); infrastructure as code 28.14-bob, Kubernetes (deklarativ orkestratsiya) ga ko'prik. Docker (28.1-2) ustiga quriladi.

Keyingi darsda konteyner optimizatsiyasini o'rganamiz: image hajmini kamaytirish (multi-stage build, yengil asoslar), qatlamlarni samarali ishlatish va tez, xavfsiz konteynerlar qurish usullari.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
28.3-dars: Docker Compose — IlmHamroh