Bir nechta muhit — override fayllar va profiles

~12 daq · Docker · Docker Compose

Muammodan boshlaylik

Ishlab chiqish uchun compose.yaml (30-dars): bind mount, npm run dev, debug porti, ochiq baza porti, Adminer. Production uchun esa butunlay boshqacha: target: production, kod image ichida, restart: unless-stopped, bazaning porti yopiq, resurs chegaralari.

Ikkita butunlay alohida fayl? Ular 80% bir xil — har o'zgarishni ikki joyda qilish kerak va ular asta-sekin bir-biridan uzoqlashadi.

Yechim — umumiy asos + muhitga xos qo'shimchalar.


Avtomatik override

Compose compose.yaml ni o'qib, yonida compose.override.yaml bo'lsa — uni avtomatik ustiga qo'shadi.

# compose.yaml — umumiy, production ga yaqin
services:
  api:
    build:
      context: .
      target: production
    restart: unless-stopped
    environment:
      DB_HOST: baza
      DB_PASSWORD: ${DB_PASSWORD:?}
    depends_on:
      baza:
        condition: service_healthy

  baza:
    image: mysql:8.4
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:?}
      MYSQL_DATABASE: dokon
    volumes:
      - baza-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "--silent"]
      interval: 5s
      retries: 20

volumes:
  baza-data:
# compose.override.yaml — faqat ishlab chiqish farqlari
services:
  api:
    build:
      target: dev
    command: npm run dev
    ports:
      - "3000:3000"
      - "9229:9229"
    volumes:
      - ./:/app
      - /app/node_modules
    environment:
      NODE_ENV: development

  baza:
    ports:
      - "127.0.0.1:3306:3306"
docker compose up -d                 # dasturchi: compose.yaml + compose.override.yaml

Birlashtirish qoidalari

  • Oddiy qiymatlar (image, command, target) — override almashtiradi
  • environment — kalitlar bo'yicha birlashtiriladi (yangilari qo'shiladi, mavjudlari almashtiriladi)
  • ports, volumes — ro'yxatlar qo'shiladi

Production fayli

# compose.prod.yaml
services:
  api:
    image: ghcr.io/kompaniya/dokon-api:${VERSIYA:?}     # registry dan, build emas (38-dars)
    ports:
      - "127.0.0.1:3000:3000"                            # reverse proxy orqali (37-dars)
    environment:
      NODE_ENV: production
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "1.0"
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

Serverda — aniq fayllar ro'yxati (override avtomatik o'qilmaydi):

docker compose -f compose.yaml -f compose.prod.yaml up -d

-f bilan fayllar ko'rsatilsa — compose.override.yaml e'tiborsiz qoldiriladi. Keyingi -f oldingisining ustidan yoziladi.

Har safar -f ... -f ... yozmaslik uchun — serverdagi .env da:

COMPOSE_FILE=compose.yaml:compose.prod.yaml

(Windows da ajratgich — ;.)

Tekshirish

docker compose -f compose.yaml -f compose.prod.yaml config

Yakuniy birlashtirilgan konfiguratsiya — production da aynan nima ishga tushishini ko'rish.


Fayllar tuzilmasi

compose.yaml              ← umumiy asos (Git)
compose.override.yaml     ← lokal ishlab chiqish (Git — jamoa uchun umumiy)
compose.prod.yaml         ← production (Git)
compose.test.yaml         ← CI testlari (Git)
.env.example              ← (Git)
.env                      ← (Git EMAS)

profiles — ixtiyoriy xizmatlar

Ba'zi xizmatlar faqat ba'zan kerak:

services:
  api:
    build: .                       # profilsiz — doim ishga tushadi

  baza:
    image: mysql:8.4               # doim

  adminer:
    image: adminer
    ports: ["127.0.0.1:8080:8080"]
    profiles: [tools]              # faqat so'ralganda

  mailpit:
    image: axllent/mailpit
    ports: ["127.0.0.1:8025:8025"]
    profiles: [tools]

  e2e:
    build: ./e2e
    profiles: [test]
    depends_on: [api]

  seed:
    build: .
    command: npm run seed
    profiles: [seed]
docker compose up -d                          # api + baza
docker compose --profile tools up -d          # + adminer + mailpit
docker compose --profile test run --rm e2e    # E2E testlar
docker compose --profile seed run --rm seed   # test ma'lumotlarini yuklash

Yoki muhit o'zgaruvchisi: COMPOSE_PROFILES=tools.


include — katta loyihalarni bo'lish

Mikroservislar yoki monorepo da:

# compose.yaml
include:
  - ./auth/compose.yaml
  - ./payments/compose.yaml
  - ./infra/compose.yaml           # baza, Redis, RabbitMQ

services:
  gateway:
    build: ./gateway

Har bir jamoa o'z xizmatining Compose faylini boshqaradi; asosiy fayl ularni birlashtiradi.


extends — umumiy sozlamani qayta ishlatish

x-umumiy: &umumiy                  # YAML anchor
  restart: unless-stopped
  logging:
    driver: json-file
    options: { max-size: "10m", max-file: "3" }

services:
  api:
    <<: *umumiy
    build: .
  worker:
    <<: *umumiy
    build: .
    command: npm run worker

x- bilan boshlanadigan kalitlar — Compose e'tiborsiz qoldiradigan "kengaytmalar". & — anchor, <<: * — uni qo'shish. Takrorlanishni kamaytiradi.


Nima uchun shunday?

Nima uchun compose.override.yaml avtomatik o'qiladi, compose.prod.yaml esa yo'q?

Xavfsiz standart: dasturchi kompyuterida docker compose up — eng ko'p bajariladigan buyruq, va u dev muhitini berishi kerak — qulay, ochiq portlar bilan. Production esa — ataylab, ongli qaror: -f compose.prod.yaml ni aniq yozish kerak. Teskarisi bo'lganida — dasturchi tasodifan production sozlamalari bilan ishga tushirardi yoki, yomonroq, serverda dev sozlamalari (ochiq baza porti, debug) bilan. "Xavfli narsa — aniq so'ralganda, xavfsiz narsa — standart".


Xulosa

Eslab qoling:

  • compose.yaml — umumiy asos; compose.override.yaml — avtomatik, ishlab chiqish uchun
  • Birlashtirish: qiymatlar almashtiriladi, environment birlashtiriladi, ro'yxatlar qo'shiladi
  • Production: -f compose.yaml -f compose.prod.yaml (override o'qilmaydi); COMPOSE_FILE
  • docker compose ... config — yakuniy natijani tekshirish
  • profiles — ixtiyoriy xizmatlar: tools, test, seed
  • include — katta loyihalarni bo'lish; x- + YAML anchor — takrorlanishsiz

Keyingi dars

32-dars: 6-bo'lim mashqlari — Node.js + MySQL + Redis