compose.yaml — services, ports, volumes, networks
Muammodan boshlaylik
O'tgan darsdagi fayl ishlaydi. Endi real loyiha uchun ko'proq sozlama kerak: build argumentlari, restart siyosati, faqat lokal portlar, tarmoqlarni ajratish, konfiguratsiya fayllari. Har bir docker run parametrining Compose dagi ekvivalentini bilish kerak.
Umumiy tuzilma
name: dokon # loyiha nomi (ixtiyoriy)
services: # xizmatlar — konteynerlar
xizmat-nomi:
...
volumes: # nomlangan volume lar
...
networks: # tarmoqlar (ixtiyoriy — standart bittasi bor)
...
[!INFO] YAML da chekinish (bo'sh joylar) — tuzilma. Tab emas, doim bo'sh joy (odatda 2 ta). Bitta noto'g'ri chekinish —
yaml: line 12: did not find expected key. Muharrir YAML kengaytmasi bilan.
image yoki build
services:
baza:
image: mysql:8.4 # tayyor image
api:
build: . # joriy papkadagi Dockerfile
admin:
build:
context: ./admin # boshqa papka
dockerfile: Dockerfile.prod
target: production # multi-stage bosqichi (16-dars)
args:
APP_VERSION: "1.4.0" # ARG (13-dars)
image: dokon-admin:1.4.0 # yasalgan image ga nom
docker run → compose
docker run |
compose.yaml |
|---|---|
--name api |
xizmat nomi (api:), yoki container_name: api |
-p 3000:3000 |
ports: ["3000:3000"] |
-e KEY=val |
environment: |
--env-file .env |
env_file: .env |
-v nom:/yo'l |
volumes: ["nom:/yo'l"] |
-v ./src:/app/src |
volumes: ["./src:/app/src"] |
--network net |
networks: [net] |
--restart unless-stopped |
restart: unless-stopped |
-w /app |
working_dir: /app |
-u 1000:1000 |
user: "1000:1000" |
--memory 512m |
deploy.resources.limits.memory: 512M |
| image dan keyingi buyruq | command: |
Portlar
ports:
- "3000:3000"
- "127.0.0.1:3306:3306" # faqat lokal (9, 25-darslar)
- "8080:80"
Portlarni qo'shtirnoqqa oling. YAML 22:22 kabi qiymatlarni ba'zan 60-lik sanoq tizimidagi son deb o'qiydi.
Faqat ichki xizmatlar (baza, Redis) — ports umuman yo'q. Compose tarmog'ida ular baribir ko'rinadi.
Muhit o'zgaruvchilari
environment:
NODE_ENV: production
DB_HOST: baza
DB_PORT: "3306" # sonlarni ham qo'shtirnoqda — string sifatida
Yoki ro'yxat shaklida:
environment:
- NODE_ENV=production
- DB_HOST=baza
Maxfiy qiymatlar faylga yozilmaydi — .env va o'zgaruvchilar (29-dars).
Volume lar
services:
baza:
image: mysql:8.4
volumes:
- baza-data:/var/lib/mysql # nomlangan volume
- ./init:/docker-entrypoint-initdb.d:ro # bind mount (nisbiy yo'l — compose.yaml ga nisbatan)
- ./mysql.cnf:/etc/mysql/conf.d/custom.cnf:ro
api:
volumes:
- uploads:/app/uploads
volumes:
baza-data:
uploads:
Nomlangan volume lar pastki volumes: bo'limida e'lon qilinishi shart, aks holda xato. Bind mount lar — yo'q.
Nisbiy yo'llar (./init) — Compose da bemalol ishlaydi va barcha OS larda bir xil ($(pwd) shart emas).
restart siyosati
restart: unless-stopped
| Qiymat | Ma'nosi |
|---|---|
no |
Hech qachon (standart) |
always |
Har doim, hatto qo'lda to'xtatilganda ham server qayta yoqilganda |
unless-stopped |
Har doim, qo'lda to'xtatilgan bo'lmasa — production uchun odatiy |
on-failure |
Faqat xato bilan chiqqanda |
Server qayta yoqildi — konteynerlar o'zi ko'tariladi. Ilova yiqildi — qayta ishga tushadi.
command va entrypoint
services:
kesh:
image: redis:7-alpine
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
worker:
build: .
command: ["node", "dist/worker.js"] # xuddi shu image — boshqa buyruq
Bitta image dan ikki xizmat: api (HTTP server) va worker (navbat ishlovchisi).
Tarmoqlar
Standart holatda — bitta umumiy tarmoq, hamma hammani ko'radi. Ajratish (24-dars):
services:
nginx:
image: nginx:1.27-alpine
ports: ["80:80"]
networks: [frontend]
api:
build: .
networks: [frontend, backend]
baza:
image: mysql:8.4
networks: [backend]
networks:
frontend:
backend:
internal: true # internetga chiqishsiz (25-dars)
Nginx bazani ko'rmaydi; baza internetga chiqa olmaydi.
To'liq misol
name: dokon
services:
api:
build:
context: .
target: production
image: dokon-api:latest
restart: unless-stopped
ports:
- "3000:3000"
environment:
NODE_ENV: production
DB_HOST: baza
DB_NAME: dokon
DB_USER: app
DB_PASSWORD: ${DB_PASSWORD}
REDIS_URL: redis://kesh:6379
volumes:
- uploads:/app/uploads
depends_on:
baza:
condition: service_healthy
kesh:
condition: service_started
baza:
image: mysql:8.4
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: dokon
MYSQL_USER: app
MYSQL_PASSWORD: ${DB_PASSWORD}
TZ: Asia/Tashkent
volumes:
- baza-data:/var/lib/mysql
- ./db/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "--silent"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
kesh:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- redis-data:/data
volumes:
baza-data:
redis-data:
uploads:
${DB_PASSWORD} — .env fayldan (29-dars). healthcheck va condition — keyingi dars.
Tekshirish
docker compose config # yakuniy konfiguratsiya: o'zgaruvchilar almashtirilgan, xatolar ko'rsatiladi
Nima uchun shunday?
Nima uchun Compose fayl formati sifatida YAML tanlangan?
YAML — inson o'qishi uchun qulay va izohlarni (#) qo'llab-quvvatlaydi; JSON da izoh yo'q va qavslar ko'p. Konfiguratsiya fayllari ko'proq o'qiladi — jamoa a'zolari, kod reviewda, yillar o'tib. Kubernetes, GitHub Actions, Ansible — DevOps vositalarining aksariyati YAML ishlatadi, shuning uchun uni bir marta o'rgansangiz, hamma joyda kerak bo'ladi. Kamchiligi — chekinishga sezgirlik; muharrirdagi YAML tekshiruvchisi bu muammoni hal qiladi.
Xulosa
Eslab qoling:
services/volumes/networks— asosiy bo'limlar; chekinish — bo'sh joyimageyokibuild(context,target,args)- Portlar qo'shtirnoqda; ichki xizmatlar —
portssiz - Nomlangan volume lar — pastda e'lon qilinadi; bind mount — nisbiy yo'l
restart: unless-stopped— production uchuncommand— bitta image dan turli xizmatlar- Tarmoqlarni ajratish,
internal: true docker compose config— tekshirish
Keyingi dars
28-dars: depends_on va healthcheck — ishga tushish tartibi