11 β Docker Compose¶
β¬ οΈ Oldingi: 10 β Volume va Docker tarmog'i Β· π README Β· Keyingi: 12 β CI/CD va GitHub Actions asoslari β‘οΈ
Bu bobda: o'nlab
docker runbuyrug'ini eslab yurish va qo'lda network/volume yaratish muammosini hal qilamiz β Docker Compose bilan butun stack (web + db + cache) bittacompose.yamlfaylda deklarativ tasvirlanadi; sintaksis (services:β versiyasiz, har servisdaimage/build,ports,environment/env_file,volumes,depends_on,healthcheck,restart), asosiy buyruqlar (docker compose up -d/down/ps/logs/exec/build),depends_on+condition: service_healthybilan to'g'ri ishga tushish tartibi,.envfayl va${O'ZGARUVCHI}, profillar (profiles) va bir nechta compose fayl (override) β hammasini haqiqiy Node "vazifalar" ilovasi misolida ko'rsatamiz va lokal Docker'da ishga tushirib tasdiqlaymiz.
Muammo: bitta ilova β o'nlab buyruq¶
10-bobda ko'rganmiz: ko'p-konteynerli ilovani to'g'ri qurish uchun tarmoq yaratish, named volume yaratish, har konteynerni alohida bayroqlar bilan ishga tushirish kerak. Bitta web + postgres + redis stack'i shunday ko'rinadi:
# β ESKI, QO'LDA USUL β har safar shu uzun ketma-ketlik
docker network create app-net
docker volume create db-data
docker run -d --name db --network app-net \
-e POSTGRES_PASSWORD=maxfiy -e POSTGRES_DB=vazifalar \
-v db-data:/var/lib/postgresql/data postgres:16-alpine
docker run -d --name cache --network app-net redis:7-alpine
docker build -t vazifalar-web .
docker run -d --name web --network app-net -p 8080:3000 \
-e DB_HOST=db -e REDIS_HOST=cache vazifalar-web
Bu yondashuvning dardlari:
- Eslab qolish qiyin β qaysi bayroq, qaysi tartib, qaysi nom edi? Bir hafta o'tib unutasiz.
- Takrorlash mumkin emas β hamkasbingiz bir xil komandani qo'lda terolmaydi; bitta bayroq tushib qolsa, stack boshqacha ishlaydi.
- Tartib muammosi β
webdbtayyor bo'lishini kutmasdan ishga tushadi va xato bilan o'ladi. - Tozalash chigal β 3 ta konteyner, 1 tarmoq, 1 volume'ni qo'lda topib o'chirish kerak.
π Yechim β deklarativ tavsif. "Qanday qilib" (imperativ buyruqlar) o'rniga "nima kerak"ni (deklarativ holat) bitta faylga yozamiz. Docker Compose shu faylni o'qib, hamma narsani o'zi yaratadi, to'g'ri tartibda ishga tushiradi va bitta buyruq bilan tozalaydi.
Quyidagi diagramma butun stack'ning bitta compose.yaml faylga jamlanishini ko'rsatadi: uchala servis bitta tarmoqda, db named volume bilan.
Birinchi compose.yaml¶
Compose fayl β bu YAML. Eng oddiy ko'rinishi: services: kaliti ostida har bir servis nomi va uning sozlamalari.
Tamom. Endi shu papkada:
Compose avtomatik tarmoq yaratdi, konteynerni ishga tushirdi va localhost:8080 da nginx ochildi. Bitta docker run ham yozmadingiz.
βΉοΈ Compose fayl nomi. Yangi tavsiya β
compose.yaml. Eskidocker-compose.ymlham hamon ishlaydi (Compose ikkalasini ham tan oladi), lekin yangi loyihalardacompose.yamlishlating. Compose ushbu nomlarni joriy papkadan avtomatik topadi β-fbermasangiz ham.β οΈ
version:kaliti ESKIRGAN. Eski qo'llanmalarda faylversion: "3.8"bilan boshlanadi. Compose v2'da bu kalit eskirgan va ortiqcha β Compose uni e'tiborsiz qoldiradi (yoki ogohlantirish beradi). Faylni to'g'ridan-to'g'riservices:bilan boshlang.
π
docker compose(probelli),docker-compose(tireli) EMAS. Tirelidocker-composeβ eski, alohida Python vositasi (Compose v1). Hozir Compose Docker'ning ichiga plagin sifatida kirgan: buyruqdocker compose(ikki so'z, probel bilan). Tireli variantni faqat juda eski tizimlarda uchratasiz β yangidocker composeni ishlating.
Servis maydonlari: nimadan tashkil topadi¶
Har bir servis ostida quyidagi asosiy maydonlar bo'ladi:
| Maydon | Vazifasi |
|---|---|
image |
Tayyor image'dan foydalanish (postgres:16-alpine) |
build |
O'z Dockerfile'ingizdan image qurish (build: .) |
ports |
Host:konteyner port publish ("8080:3000") |
environment |
Muhit o'zgaruvchilari (key: value) |
env_file |
O'zgaruvchilarni fayldan o'qish (.env) |
volumes |
Named volume yoki bind mount ulash |
depends_on |
Ishga tushish tartibi (qaysi servisdan keyin) |
healthcheck |
Servis "sog'lom"ligini aniqlash usuli |
restart |
Qayta ishga tushirish siyosati |
image va build β ikki muqobil: yo tayyor image olasiz, yo o'zingiz quryapsiz.
services:
db:
image: postgres:16-alpine # tayyor image β Docker Hub'dan tortiladi
web:
build: . # joriy papkadagi Dockerfile'dan quriladi
build ni batafsilroq ham yozish mumkin:
web:
build:
context: . # qaysi papkadan
dockerfile: Dockerfile # qaysi Dockerfile (boshqa nom bo'lsa)
environment va env_file¶
Konteynerga o'zgaruvchi uzatishning ikki yo'li:
db:
environment: # to'g'ridan-to'g'ri faylda
POSTGRES_USER: postgres
POSTGRES_PASSWORD: maxfiy_parol
POSTGRES_DB: vazifalar
yoki alohida fayldan:
π‘ Maslahat: maxfiy ma'lumotni (parol, token)
compose.yamlichiga yozmang β uni.envfaylga qo'ying va.envni.gitignorega kiriting. Compose.envni avtomatik o'qiydi (buni quyida ko'ramiz). Shunda config Git'da, sirlar esa repodan tashqarida qoladi.
restart siyosati¶
unless-stopped β konteyner xato bilan o'lsa yoki server qayta yuklansa, Docker uni avtomatik qayta ishga tushiradi; ammo siz qo'lda docker compose stop qilsangiz, qayta tushirmaydi. Production uchun eng ko'p ishlatiladigan, mantiqiy variant. (Muqobillari: no β hech qachon, always β har doim, on-failure β faqat xatoda.)
depends_on va healthcheck: to'g'ri tartib¶
Eng ko'p uchraydigan xato: web ishga tushib db ga ulanmoqchi bo'ladi, lekin postgres hali ulanishlarni qabul qilishga tayyor emas β web xato bilan o'ladi.
depends_on ishga tushish tartibini beradi, lekin oddiy holatda u faqat konteyner boshlanishini kutadi, "tayyorligini" emas. Postgres'ning konteyneri boshlangani bilan, ichidagi baza bir necha soniyadan keyin tayyor bo'ladi. Yechim β healthcheck bilan birga ishlatish:
services:
web:
build: .
depends_on:
db:
condition: service_healthy # db SOG'LOM bo'lgachgina web ishga tushadi
cache:
condition: service_healthy
db:
image: postgres:16-alpine
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d vazifalar"]
interval: 5s
timeout: 3s
retries: 5
healthcheck Docker'ga "bu servis tayyormi?" degan savolni qanday tekshirishni aytadi:
testβ ishga tushiriladigan buyruq;0qaytarsa sog'lom, aks holda kasal.CMD(to'g'ridan-to'g'ri buyruq) yokiCMD-SHELL(shell orqali, o'zgaruvchilar bilan).intervalβ necha vaqtda bir tekshirish (5s).timeoutβ bir tekshiruv qancha kutadi.retriesβ necha marta kasal bo'lsa, "unhealthy" deb belgilash.
Quyidagi diagramma bu tartibni ko'rsatadi: avval db va cache "healthy" bo'ladi, keyingina web ishga tushadi.
π Qoida:
depends_on+condition: service_healthy= bog'liq servis HAQIQATAN tayyor bo'lguncha web kutadi. Healthcheck'sizdepends_onfaqat "konteyner boshlandi" deb biladi, "baza ulanishga tayyor" deb emas. DB/cache uchun har doim healthcheck qo'shing.
Redis uchun healthcheck oddiyroq:
cache:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"] # PONG qaytarsa sog'lom
interval: 5s
timeout: 3s
retries: 5
To'liq stack: vazifalar ilovasi¶
Endi haqiqiy stack quramiz: Node (Express) "vazifalar" API + postgres + redis. Web db'ga nom bilan (db), redis'ga nom bilan (cache) ulanadi β IP'siz, 10-bobdagi user-defined bridge tamoyili bo'yicha. Compose tarmoqni va undagi DNS'ni avtomatik beradi.
Ilova kodi (server.js, soddalashtirilgan) db va redis'ga muhit o'zgaruvchisidagi xost nomi orqali ulanadi:
const pool = new pg.Pool({
host: process.env.DB_HOST || "db", // konteyner NOMI, IP emas
port: 5432,
user: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
database: process.env.POSTGRES_DB,
});
const redis = createClient({ url: `redis://${process.env.REDIS_HOST || "cache"}:6379` });
Dockerfile (8-bobdagidek, healthcheck bilan):
FROM node:22-alpine
LABEL org.opencontainers.image.title="vazifalar-web"
WORKDIR /app
COPY package.json ./
RUN npm install --omit=dev
COPY server.js ./
EXPOSE 3000
HEALTHCHECK --interval=10s --timeout=3s --start-period=5s --retries=5 \
CMD wget -qO- http://localhost:3000/ || exit 1
CMD ["node", "server.js"]
Va asosiy compose.yaml β butun stack:
services:
web:
build: .
ports:
- "${WEB_PORT:-8080}:3000"
environment:
DB_HOST: db
REDIS_HOST: cache
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
depends_on:
db:
condition: service_healthy
cache:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 3s
retries: 5
restart: unless-stopped
cache:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
restart: unless-stopped
volumes:
db-data:
Diqqat qiling:
- Tarmoq yo'q? To'g'ri β Compose avtomatik
<loyiha>_defaultnomli user-defined bridge yaratadi va hamma servisni shunga qo'shadi. Shuning uchun webdbvacacheni nom bilan topadi. Qo'lda tarmoq yozish shart emas. dbvacachedaportsyo'q β ular faqat ichki tarmoqda yashaydi, tashqariga ochilmaydi (10-bobdagi xavfsizlik qoidasi). Faqatwebpublish qilingan.- Pastdagi
volumes:bo'limi β named volume'ni e'lon qiladi; Compose uni<loyiha>_db-datadeb yaratadi.
.env fayli (parol va port shu yerda):
${POSTGRES_USER}, ${WEB_PORT:-8080} β Compose .env faylidan o'zgaruvchi o'rniga qo'yadi. ${WEB_PORT:-8080} degani: WEB_PORT aniqlanmagan bo'lsa, standart 8080 ishlat.
Ishga tushiramiz¶
[+] Running 4/4
β Network vazifalar_default Created
β Container vazifalar-cache-1 Healthy
β Container vazifalar-db-1 Healthy
β Container vazifalar-web-1 Started
E'tibor bering: cache va db avval Healthy bo'ldi, keyingina web Started β condition: service_healthy aynan shuni qildi. Holatni ko'ramiz:
NAME SERVICE STATUS PORTS
vazifalar-cache-1 cache Up (healthy) 6379/tcp
vazifalar-db-1 db Up (healthy) 5432/tcp
vazifalar-web-1 web Up (healthy) 0.0.0.0:8080->3000/tcp
Endi API ishlashini tekshiramiz:
curl localhost:8080/
# Vazifalar API ishlayapti
curl -X POST localhost:8080/vazifalar -H "Content-Type: application/json" \
-d '{"matn":"compose sinovi"}'
# {"id":1,"matn":"compose sinovi"}
curl localhost:8080/vazifalar
# {"vazifalar":[{"id":1,"matn":"compose sinovi"}],"sorovlar":1}
Web postgres'ga (db) yozdi va redis'dan (cache) so'rovlar sonini oldi β ikkalasiga ham nom bilan ulandi. Web konteyner ichidan tekshirsak, nom IP'ga yechiladi:
π‘ Sir:
compose.yamlda servis nomi (db,cache) β bu o'sha servis uchun tarmoq xost nomi. Ilovangiz kodida ulanish satrinipostgres://db:5432/vazifalardeb yozasiz βdbaynan compose'dagi servis nomi. IP hech qachon kerak emas.
Compose buyruqlari¶
Stack lifecycle'ni bir necha buyruq boshqaradi. Quyidagi diagramma asosiy up/down aylanishini ko'rsatadi.
docker compose up -d # stack'ni ko'tarish (detached, fonda)
docker compose up -d --build # ko'tarishdan oldin image'larni qayta qurish
docker compose ps # servislar holati (Up/healthy)
docker compose logs -f # barcha servis loglarini kuzatish (follow)
docker compose logs -f web # faqat bitta servis logi
docker compose exec web sh # ishlab turgan web ichida buyruq/shell
docker compose build # faqat build (ishga tushirmasdan)
docker compose pull # image'larni registry'dan yangilab tortish
docker compose restart web # bitta servisni qayta ishga tushirish
docker compose stop # to'xtatish (o'chirmasdan)
docker compose down # stack'ni to'xtatish + konteyner/tarmoqni o'chirish
docker compose down -v # ... volume'larni HAM o'chirish (ma'lumot yo'qoladi!)
down va down -v farqi muhim:
docker compose downβ konteynerlar va tarmoqni o'chiradi, named volume'lar qoladi β ma'lumot saqlanadi.docker compose down -vβ volume'larni ham o'chiradi β DB ma'lumoti butunlay yo'qoladi.
β οΈ
down -vehtiyot bo'lib.-vnamed volume'larni o'chiradi β postgres ma'lumotingiz bilan. Uni faqat "toza boshlamoqchiman" deganda ishlating. Production'dadown -vβ xavfli buyruq.βΉοΈ Eski qo'llanmalarda
docker-compose up(tireli) ko'rasiz β bu eski v1 vositasi. Yangidocker compose up(probelli) ishlating; bayroqlar deyarli bir xil.
.env fayl va o'zgaruvchilar¶
Compose joriy papkadagi .env faylini avtomatik o'qiydi va ${...} o'zgaruvchilarni o'rniga qo'yadi. Bu config'ni muhitga moslashtirishning eng oddiy yo'li.
config buyrug'i bilan o'rniga qo'yilgan holatni ko'rishingiz mumkin β bu xatolarni topishning eng yaxshi usuli:
Bu compose faylni parse qiladi, normalizatsiya qiladi va ${...} o'zgaruvchilar to'ldirilgan to'liq, tekshirilgan holatni chiqaradi. Yozishda xato bo'lsa β shu yerda ko'rinadi.
π‘ Maslahat: har deploy oldidan
docker compose configni ishga tushiring. U YAML sintaksisini, o'zgaruvchi o'rin qo'yishni va struktura xatolarini ilova ko'tarilmasdan oldin topadi. "Avval validatsiya, keyinup" β yaxshi odat.
Profillar: ixtiyoriy servislar¶
Ba'zi servislar har doim kerak emas β masalan, adminer (DB ko'rish UI'si) faqat dev'da kerak. profiles shu servisni standartda o'chiq qiladi, faqat profil tanlanganda yoqiladi:
services:
web:
image: nginx:1.27-alpine
adminer:
image: adminer:latest
profiles:
- tools # faqat "tools" profilida yoqiladi
docker compose up -d # faqat web β adminer ishga tushmaydi
docker compose --profile tools up -d # web + adminer
Bu DB admin paneli, test ma'lumotini to'ldiruvchi, debug vositalari kabi "kerak bo'lganda" servislar uchun qulay.
Bir nechta compose fayl: override¶
Compose joriy papkadagi compose.yaml ustiga compose.override.yaml (bo'lsa) ni avtomatik birlashtiradi. Bu dev va prod sozlamalarini ajratishning standart usuli: asosiy fayl umumiy, override esa dev'ga xos qo'shimchalar.
compose.yaml (asosiy, prod'ga mos):
compose.override.yaml (dev β avtomatik yuklanadi):
docker compose up -d
# avtomatik: compose.yaml + compose.override.yaml birlashadi
# natija: MODE=dev (map almashtiriladi); portlar BIRLASHADI -> asosiy port VA 8080 ikkalasi ochiq
docker compose -f compose.yaml up -d
# faqat asosiy fayl: port 80, override e'tiborga olinmaydi
π Qoida:
-fbermasangiz, Composecompose.yaml+compose.override.yamlni avtomatik birlashtiradi. β οΈ Diqqat: birlashtirishda ro'yxat (list) maydonlari βports,volumes,exposeβ QO'SHILADI (append), almashtirilmaydi; faqat skalyar va map maydonlar (masalanenvironmentkalitlari,image) almashtiriladi. Shuning uchun override'daportsbersangiz, asosiy portlar ham ochiq qoladi. Aniq fayl(lar)ni ko'rsatsangiz (-f a.yaml -f b.yaml), faqat o'shalar β keyingisi avvalgisini bekor qiladi (override). Prod deploy'da odatda-f compose.yaml -f compose.prod.yamldeb aniq beriladi.
11-bob mashqlari¶
Quyidagi mashqlarni o'zingiz yozing va
docker compose up -dbilan ishga tushiring. Tugagachdocker compose down -vbilan tozalashni unutmang.
Oson¶
- Bitta servisli (
nginx:1.27-alpine, port8080:80)compose.yamlyozing,docker compose up -dqiling vahttp://localhost:8080ochiq ekanini tekshiring. So'ngdocker compose downbilan tozalang. - Yuqoridagi faylga eskirgan
version: "3.8"qatorini qo'shibdocker compose configqiling β Compose ogohlantirish berishini yoki uni e'tiborsiz qoldirishini kuzating, so'ng qatorni olib tashlang. docker compose ps,docker compose logs,docker compose stop,docker compose downbuyruqlari nima qilishini o'z so'zingiz bilan yozing.docker-compose(tireli) vadocker compose(probelli) farqini ayting: qaysi biri zamonaviy va nega?.envfayldaWEB_PORT=9090yozing, compose faylda"${WEB_PORT:-8080}:80"ishlating vadocker compose configchiqishida portning9090bo'lganini tasdiqlang.
O'rta¶
web(nginx) vadb(postgres:16-alpine) ikki servisli stack yozing;dbga named volume va healthcheck (pg_isready) qo'shing,webesadbgacondition: service_healthybilan bog'lansin.
Yechim
services:
web:
image: nginx:1.27-alpine
ports:
- "8080:80"
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: test
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 5
volumes:
db-data:
docker compose configbilan compose faylingizni validatsiya qiling. Faylga ataylab xato kiriting (masalanports:o'rnigaport:) vaconfigqanday xato berishini ko'ring.
Yechim
`config` faylni parse va normalizatsiya qiladi; struktura xatolarini `up` dan oldin topadi. Deploy oldidan har doim ishga tushiring.environmento'rnigaenv_file: [.env]ishlating: postgres parolini.envfaylga qo'ying vacompose.yamlda to'g'ridan-to'g'ri yozmang.docker compose configda parol o'rniga qo'yilganini ko'ring.
Yechim
`.env`: `compose.yaml`: Sirlar `.env` da (repodan tashqarida, `.gitignore`), config esa Git'da qoladi.profilesishlating:adminerservisinitoolsprofiliga qo'ying vadocker compose config --servicesbilan standartda ko'rinmasligini,--profile toolsbilan ko'rinishini tasdiqlang.
Yechim
Profil tanlanmasa, servis o'chiq qoladi β dev-only vositalar uchun ideal.restart: unless-stoppedni servisga qo'shing, konteynernidocker compose up -dqiling, so'ng ichidagi jarayonni o'ldiring (docker compose exec ... kill 1) va Docker uni avtomatik qayta ko'targaninidocker compose psda kuzating.
Qiyin¶
-
To'liq stack yozing: Node/Express web (
build: .) +postgres:16-alpine(named volume + healthcheck) +redis:7-alpine(healthcheck). Web db'ga va redis'ga nom bilan ulansin,.envdan port va parol kelsin.up -dqiling,psda hammasi(healthy)ekanini,curlbilan API ishlashini tasdiqlang, so'ngdown -vbilan tozalang.Yechim
compose.yaml:services: web: build: . ports: - "${WEB_PORT:-8080}:3000" environment: DB_HOST: db REDIS_HOST: cache POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} depends_on: db: condition: service_healthy cache: condition: service_healthy restart: unless-stopped db: image: postgres:16-alpine environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - db-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 5s timeout: 3s retries: 5 restart: unless-stopped cache: image: redis:7-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 restart: unless-stopped volumes: db-data:docker compose up -d --build docker compose ps # hammasi Up (healthy) curl localhost:8080/vazifalar # {"vazifalar":[...],"sorovlar":N} docker compose exec web getent hosts db # db nomi IP'ga yechiladi docker compose down -v # to'liq tozalashBu bobda yozilgan asosiy stack β aynan shu. Compose tarmoqni va DNS'ni avtomatik beradi, depends_on healthcheck to'g'ri tartibni ta'minlaydi.
-
depends_onni healthcheck'siz ishlatib, web db tayyor bo'lishini KUTMAY ishga tushishini kuzating (ehtimol web xato beradi), so'ng healthcheck +condition: service_healthyqo'shib muammo yo'qolishini ko'rsating.Yechim
Web postgres ulanishlarni qabul qilishidan oldin ulanmoqchi bo'lib xato berishi mumkin (ayniqsa birinchi ishga tushishda, baza initsializatsiyasi davom etayotganda).# β healthcheck'siz: web db boshlanishini kutadi, lekin "tayyor"ligini emas services: web: build: . depends_on: - db # faqat tartib β db boshlangach darrov web ham boshlanadi db: image: postgres:16-alpine environment: POSTGRES_PASSWORD: test# β healthcheck + condition: web db SOG'LOM bo'lgachgina ishga tushadi services: web: build: . depends_on: db: condition: service_healthy db: image: postgres:16-alpine environment: POSTGRES_PASSWORD: test healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 3s retries: 5condition: service_healthyβdepends_onni "tayyorlik"ka bog'laydi. DB/cache uchun har doim shunday qiling. -
Override mexanizmini ko'rsating:
compose.yaml(port80:80) vacompose.override.yaml(port8080:80+MODE: dev) yozing.docker compose configda ikkalasi birlashganini (port 8080, MODE dev),docker compose -f compose.yaml configda esa faqat asosiy fayl (port 80) ishlatilishini tasdiqlang.Yechim
compose.yaml:compose.override.yaml:docker compose config # birlashadi: portlar 80 VA 8080 (ro'yxat qo'shiladi), MODE=dev docker compose -f compose.yaml config # faqat asosiy: port 80, MODE yo'q-fbermasangiz override avtomatik qo'shiladi; aniq-fbersangiz faqat ko'rsatilgan fayl(lar) ishlatiladi. Bu dev/prod ajratishning standart usuli.
β¬ οΈ Oldingi: 10 β Volume va Docker tarmog'i Β· π README Β· Keyingi: 12 β CI/CD va GitHub Actions asoslari β‘οΈ