SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-10-28

Docker Compose में multiple files का उपयोग कैसे करें

Docker Compose में compose.override.yaml के ऑटो-लोडिंग व्यवहार, फाइलों के मर्जिंग क्रम और ports कॉन्फ़िगरेशन की समस्याओं को समझें। dev और prod वातावरण के लिए include का सही उपयोग सीखें।

एक से अधिक फाइलों के साथ Compose क्या करता है

Docker Compose एक ही प्रोजेक्ट को कई फाइलों से बना सकता है। यह उन्हें उसी क्रम में पढ़ता है जिस क्रम में वे प्राप्त होती हैं और उन्हें एक एकल मॉडल में मर्ज कर देता है, इसलिए किसी भी conflicting मान पर बाद वाली फाइल प्रभावी होती है। कमांड लाइन से ऐसा करने के दो तरीके हैं: एक override फाइल जिसे Compose अपने आप लोड करता है, और -f फ्लैग जिसे आप मैन्युअल रूप से पास करते हैं। तीसरा तरीका फाइल के अंदर ही मौजूद होता है, जो include एलिमेंट है, और यह दोनों से अलग तरीके से काम करता है।

मर्जिंग केवल साधारण ओवरराइट नहीं है। Mappings की-दर-की मर्ज होती हैं, sequences जुड़ जाती हैं (append), और कुछ चुनिंदा fields पूरी तरह से बदल दी जाती हैं। यही अंतर आश्चर्य का कारण बनता है, और ports सूची वह है जो लगभग हर किसी को उलझा देती है।

नीचे दी गई हर जानकारी Compose v2 या उसके बाद के वर्ज़न पर आधारित है, जो पुराने docker-compose स्क्रिप्ट के बजाय docker compose प्लगइन का उपयोग करता है। वर्तमान रिलीज़ v5 नंबर वाली हैं, और प्लगइन उसी तरह काम करता है। जाँचने के लिए docker compose version चलाएँ। यदि आपने अभी तक कोई Compose फाइल नहीं लिखी है, तो Docker Compose बेसिक्स गाइड से शुरुआत करें और फिर वापस आएँ।

वह override file जिसे Compose बिना बताए लोड करता है

यदि आप docker compose up को बिना किसी -f flag के चलाते हैं, तो Compose वर्तमान directory और उसके parent directories में compose.yaml या docker-compose.yaml को खोजता है। यदि base file के साथ कोई override file मौजूद होती है, तो Compose उसे अपने आप दूसरे नंबर पर लोड कर लेता है।

ls compose.yaml compose.override.yaml
docker compose up -d

दोनों फाइलें मौजूद होने पर, यह वैसा ही है जैसे उन्हें मैन्युअल रूप से टाइप किया गया हो।

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

Compose जिन नामों को पहचानता है वे हैं compose.override.yaml, compose.override.yml, और पुराने docker-compose.override.yml तथा docker-compose.override.yaml। कोई अन्य नाम, जैसे कि compose.dev.yaml, केवल तभी लोड होता है जब आप उसे -f के साथ निर्दिष्ट करते हैं।

जैसे ही आप एक -f पास करते हैं, automatic loading बंद हो जाती है। docker compose -f compose.yaml up केवल उसी एक फाइल को पढ़ता है और override को अनदेखा कर देता है। इसी विशेषता पर इस गाइड में बाद में बताया गया dev और prod पैटर्न आधारित है।

सर्वर पर इसका असर दोनों दिशाओं में हो सकता है। deploy directory में रखी गई override file उस directory से चलने वाले हर bare docker compose command द्वारा load होती है, जिसमें आपका cron job चलाने वाला command भी शामिल है। इसी कारण production stack ऐसी source directory को bind-mount कर सकता है जिसे deploy करने का किसी का इरादा नहीं था। हर deploy के बाद docker compose config चलाएँ और उसका output पढ़ें। जब deploy unattended हो, तो यह जाँच तभी उपयोगी है जब कोई आपको failure की सूचना दे। यही काम self-hosted ntfy server जैसे push channel का है, जिस पर cron job या systemd OnFailure unit notification भेज सकती है।

-f के साथ क्रम निर्धारण, और रिलेटिव पाथ कहाँ रिजॉल्व होते हैं

Compose आपके द्वारा दी गई फाइलों के क्रम में कॉन्फ़िगरेशन बनाता है, और बाद वाली फाइलें पिछली फाइलों को ओवरराइड करती हैं और उनमें जुड़ती हैं। बाएं से दाएं, अंतिम फाइल प्रभावी होती है।

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

उस project में हर command के लिए वही file list होनी चाहिए। दो files के साथ up और एक file के साथ logs चलाने पर आप किसी अलग merged model के साथ काम कर रहे होते हैं। इससे ऐसी service बन सकती है जिसे Compose मौजूद नहीं मानता। यह जोखिम उस stack में और बढ़ जाता है जिसमें upgrades one-off commands से चलते हैं, जैसे self-hosted Chatwoot support desk में database migration step। वहाँ गलत file list के साथ जारी किया गया docker compose run चुपचाप उस model को target करता है जो आपकी services पहले से उपयोग कर रही model से अलग है। इसके बजाय COMPOSE_FILE environment variable से list को एक बार निर्धारित करें।

export COMPOSE_FILE=compose.yaml:compose.prod.yaml
docker compose config
docker compose up -d

Linux पर सेपरेटर : है, और COMPOSE_PATH_SEPARATOR इसे बदल देता है। COMPOSE_FILE को प्रोजेक्ट की .env फाइल में भी रखा जा सकता है, जिससे यह आपके शेल हिस्ट्री के बजाय चेकआउट का हिस्सा बन जाता है। कमांड लाइन पर स्पष्ट रूप से सेट की गई कोई भी चीज़ एनवायरनमेंट वेरिएबल से अधिक प्रभावी होती है।

अब वह नियम जो बाइंड माउंट्स (bind mounts) को प्रभावित करता है। जब आप -f के साथ कई फाइलों का उपयोग करते हैं, तो उन सभी फाइलों में मौजूद सभी रिलेटिव पाथ पहली फाइल की डायरेक्टरी के सापेक्ष रिजॉल्व होते हैं, न कि उस फाइल के सापेक्ष जिसमें वे लिखे गए हैं। यदि आप deploy/prod/compose.prod.yaml के अंदर ./data:/var/lib/postgresql/data लिखते हैं, तो भी Compose ./data को बेस फाइल के बगल में ही खोजेगा। Docker तब उस गलत पाथ पर एक खाली डायरेक्टरी बना देता है और कंटेनर बिना किसी डेटा के स्टार्ट होता है, जो डेटा लॉस जैसा दिखता है, लेकिन ऐसा होता नहीं है। बेस पाथ को स्वयं सेट करने के लिए --project-directory पास करें, या include का उपयोग करें, जो प्रत्येक फाइल को उसकी अपनी डायरेक्टरी के सापेक्ष रिजॉल्व करता है।

प्रोजेक्ट का नाम उसी बेस डायरेक्टरी से आता है, इसलिए पहली फाइल को बदलने से प्रोजेक्ट का नाम बदल सकता है। प्रोजेक्ट का नाम बदलने का मतलब है नए कंटेनर नाम और नए वॉल्यूम नाम, और पुराना वॉल्यूम अभी भी पुराने नाम के तहत डिस्क पर मौजूद रहता है। इसके बजाय, बेस फाइल में टॉप-लेवल name: के साथ इसे पिन करें।

name: myapp

कौन से fields मर्ज होते हैं और कौन से replace किए जाते हैं

Compose fields को उनके नाम से नहीं, बल्कि value के प्रकार के आधार पर मर्ज करता है।

  • Single-valued fields को replace किया जाता है। image, command, entrypoint और mem_limit बाद वाली value को पूरी तरह से अपना लेते हैं। आप किसी command में एक argument को append नहीं कर सकते, क्योंकि override पूरी लाइन को फिर से लिख देता है।
  • Mappings को key-by-key मर्ज किया जाता है। environment, labels, volumes और devices दोनों फाइलों की सभी keys को बनाए रखते हैं, और दोनों में मौजूद किसी भी key के लिए बाद वाली फाइल की value प्रभावी होती है। environment और labels के लिए key, variable या label का नाम होती है। volumes और devices के लिए key, container का path होती है।
  • Sequences को append किया जाता है। dns, dns_search, expose, tmpfs और external_links को आपस में जोड़ दिया जाता है। एक base जिसमें expose: ["3000"] है, उसे एक override के साथ मर्ज करने पर जिसमें ["4000", "5000"] है, परिणाम ["3000", "4000", "5000"] मिलता है।

चार sequences में एक identity key होती है, इसलिए उस key पर मेल खाने वाली entries append होने के बजाय मर्ज हो जाती हैं। volumes, secrets और configs, target पर मेल खाती हैं। ports, ip, target, published और protocol के संयोजन पर मेल खाती है।

उस ports नियम को दो बार पढ़ें, क्योंकि यही वह जगह है जहाँ गलती हो सकती है। दो port entries केवल तभी एक ही entry मानी जाती हैं जब वे चारों भाग आपस में मेल खाते हों। उनमें से किसी एक को भी बदलने पर Compose उसे एक दूसरी, असंबंधित port के रूप में देखता है, इसलिए वह दोनों को बनाए रखता है।

आपका port override के बाद भी published क्यों रहता है

एक base file जो हर interface पर service को publish करती है:

services:
  web:
    image: nginx:1.27
    ports:
      - "8080:80"

एक override जिसे केवल localhost पर bind करने के लिए लिखा गया है, क्योंकि इसके सामने एक reverse proxy होगा:

services:
  web:
    ports:
      - "127.0.0.1:8080:80"

यह मानने से पहले कि यह काम कर गया, परिणाम की जाँच करें।

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

दोनों entries output में मौजूद हैं। ip भाग अलग है, 0.0.0.0 बनाम 127.0.0.1, इसलिए merge के संदर्भ में ये दो अलग ports हैं, और public binding जिसे आप हटाना चाहते थे, वह अभी भी model में है। यह Docker पर अन्य जगहों की तुलना में अधिक मायने रखता है, क्योंकि एक published port आपके firewall rules से पहले iptables में लिख दिया जाता है। यह mechanism why published Docker ports walk past ufw में कवर किया गया है।

इसके दो समाधान हैं। स्पष्ट समाधान !override tag है, जो पूरे attribute को replace कर देता है और merge rules को छोड़ देता है:

services:
  web:
    ports: !override
      - "127.0.0.1:8080:80"

!override के लिए Compose v2.24.4 या उससे नया version चाहिए। portable समाधान के लिए किसी tag की आवश्यकता नहीं है: ports को base file से पूरी तरह बाहर रखें और इसे केवल environment-specific files में ही declare करें। जब merge करने के लिए कुछ नहीं होगा, तो कुछ भी leak नहीं होगा। नीचे दिए गए worked example में इसी pattern का उपयोग किया गया है।

बेस फाइल सेट से किसी वैल्यू को हटाना

!reset एक एट्रिब्यूट को हटा देता है, उसे वापस उसके डिफ़ॉल्ट मान या null पर सेट कर देता है। यह एक वैल्यू लेता है और उसे अनदेखा कर देता है, इसलिए कुछ वैध और खाली लिखें।

services:
  web:
    ports: !reset []
    environment:
      DEBUG: !reset null

!reset, Compose v2.18.0 या उसके बाद के वर्ज़न पर काम करता है, जो !override के आने से कई रिलीज़ पहले आया था। इसका उपयोग तब करें जब बेस फ़ाइल को एडिट करना आपके अधिकार में न हो, उदाहरण के लिए कोई वेंडर फ्रैगमेंट जिसे आप पुल करते हैं। एक पब्लिश्ड अपस्ट्रीम स्टैक बिल्कुल ऐसा ही मामला है: एक self-hosted AFFiNE workspace के पीछे की Compose फ़ाइल चार ऐसे कंटेनर घोषित करती है जिन्हें आपने नहीं लिखा है, और !reset आपको उनमें से किसी एक पर एक एट्रिब्यूट को क्लियर करने की सुविधा देता है, बिना फ़ाइल को फ़ॉर्क किए और उसे ट्रैक करने की ज़िम्मेदारी लिए।

include, उन stacks के लिए जो अलग-अलग हिस्सों से बने हैं

include आपके model में एक और Compose application को शामिल करता है। यह एक top-level element है, flag नहीं।

include:
  - path: ../commons/compose.yaml

include में प्रत्येक path को उसके अपने Compose application model के रूप में load किया जाता है, जिसका अपना project directory होता है। इसलिए उस file के भीतर के relative paths उसी file की directory के अनुसार resolve होते हैं। -f से यही वास्तविक अंतर है, और यही कारण है कि जब fragment किसी अन्य folder या repository में स्थित हो, तो include ही सही tool है। यह किसी ऐसे vendor stack का सामान्य स्वरूप है जिसे आपने नहीं लिखा है: a self-hosted Authentik SSO install के पीछे की multi-service Compose file अपनी directory में अपने relative paths के साथ सुरक्षित रह सकती है, जबकि आपकी file केवल आपकी अपनी services तक सीमित रहती है।

इसका long form sub-options लेता है।

include:
  - path:
      - ../monitoring/compose.yaml
      - ../monitoring/compose.vps.yaml
    project_directory: ../monitoring
    env_file: ../monitoring/.env

path एक list स्वीकार करता है, और उन files को आपके model में शामिल होने से पहले सामान्य नियमों के साथ merge किया जाता है। project_directory उस base path को set करता है जिसका उपयोग included file में relative paths को resolve करने के लिए किया जाता है। env_file उस file का नाम तय करता है जिससे included Compose file अपने interpolation defaults लेती है। यह पहले से ही उस file की अपनी project directory में मौजूद .env पर default होता है, और आपके local project का environment अभी भी उस पर प्राथमिकता रखता है। इसी तरह आप fragment को edit किए बिना उसके किसी variable को override करते हैं। include के लिए Compose v2.20.0 या उससे नया version चाहिए। यही options उस stack के लिए भी उपयुक्त हैं जिसे आप पहले से चला रहे हैं, जैसे Halcyon, which reskins a Jellyfin library as a 90s rental store: इसकी file अपना image tag और अपना env_file बरकरार रखती है, इसलिए इसे upgrade करने का मतलब उस file को छूना नहीं है जिसमें आपका media stack स्थित है।

Docker का documentation कहता है कि यदि कोई resource name आपकी file और included file दोनों में घोषित है, तो उसे conflict मानकर reject कर दिया जाता है। वर्तमान release में loader ऐसा नहीं करता है: Compose v5.6.1 के अनुसार, और 2026-10-27 को loader source की जाँच करने पर, यह दोनों definitions को merge कर देता है, जहाँ किसी भी conflicting value के लिए आपकी file को प्राथमिकता दी जाती है, न कि error के साथ रुकने के। इसलिए इस पर भरोसा न करें कि duplicate name होने पर प्रक्रिया रुक जाएगी। included file द्वारा घोषित किसी चीज़ को बदलने के लिए, उस बदलाव को compose.override.yaml में रखें: override को assembled model पर लागू किया जाता है, इसलिए बदलाव स्पष्ट होता है और इस बात पर निर्भर नहीं करता कि कोई विशेष release टकराव को कैसे संभालती है। यह आदत उन stacks के साथ सबसे अधिक फायदेमंद होती है जिनकी upstream file हर release पर फिर से लिखी जाती है, जैसे PhotoPrism versus Immich में वर्णित multi-container photo servers, जहाँ localhost binding या extra volume को उस file के बजाय आपके override में होना चाहिए जिसे अगला upgrade बदल देगा।

संक्षेप में: include अलग-अलग applications को जोड़ता है, -f एक ही application पर configuration की परतें चढ़ाता है।

एक VPS पर dev और prod का विभाजन

यहाँ पूरा पैटर्न तीन फाइलों में दिया गया है। बेस फाइल यह घोषित करती है कि हर जगह क्या लागू होगा, और यह कोई भी पोर्ट पब्लिश नहीं करती है।

name: myapp

services:
  app:
    image: ghcr.io/example/app:1.4.2
    environment:
      DATABASE_URL: postgres://app:${POSTGRES_PASSWORD}@db:5432/app
      LOG_LEVEL: info
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_DB: app
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  db_data:

depends_on कंडीशन वह है जो ऐप को ऐसे डेटाबेस के लिए प्रतीक्षा करने पर मजबूर करती है जो वास्तव में रिस्पॉन्स दे रहा हो, न कि केवल ऐसे कंटेनर के लिए जो अस्तित्व में है। इसकी व्याख्या healthchecks और depends_on कंडीशंस में की गई है। POSTGRES_PASSWORD को प्रोजेक्ट की .env फाइल से इंटरपोलेट किया जाता है, जिसे कभी भी git में नहीं डालना चाहिए। सुरक्षित विकल्पों के लिए env फाइल्स और Compose सीक्रेट्स देखें।

अगली फाइल compose.override.yaml है, जिसे Compose अपने आप लोड कर लेता है। यह डेवलपर की फाइल है।

services:
  app:
    build: .
    command: npm run dev
    environment:
      LOG_LEVEL: debug
    ports:
      - "3000:3000"
    volumes:
      - ./src:/app/src

  db:
    ports:
      - "127.0.0.1:5432:5432"

लैपटॉप पर, एक साधारण docker compose up इन दोनों फाइलों को मर्ज कर देता है। command इमेज के डिफॉल्ट को बदल देता है क्योंकि यह सिंगल-वैल्यूड है। LOG_LEVEL, info की जगह ले लेता है क्योंकि environment की-आधारित मर्जिंग करता है। बाइंड माउंट और दो पब्लिश किए गए पोर्ट पूरी तरह से अतिरिक्त हैं, और डेटाबेस पोर्ट को localhost पर बाइंड किया गया है ताकि साझा नेटवर्क पर मौजूद लैपटॉप कमरे में किसी और को PostgreSQL उपलब्ध न कराए।

अंत में, compose.prod.yaml। इसका नाम ऐसा नहीं है जिसे Compose खुद खोजे, इसलिए यह गलती से कभी लोड नहीं होती है।

services:
  app:
    ports:
      - "127.0.0.1:8000:3000"
    deploy:
      resources:
        limits:
          memory: 512M

VPS पर आप दोनों फाइलों का नाम निर्दिष्ट करते हैं, और नाम देने की यह क्रिया ही ओवरराइड फाइल को बाहर रखती है।

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

ps में दोनों सर्विसेज रनिंग दिखनी चाहिए, और db में (healthy) दिखाई देना चाहिए। चूंकि आपने -f पास किया था, इसलिए compose.override.yaml को नहीं पढ़ा गया। इस कारण dev कमांड, सोर्स बाइंड माउंट और पब्लिक पोर्ट 3000 प्रोडक्शन तक नहीं पहुँच सकते, भले ही फाइल उसी डायरेक्टरी में मौजूद हो। पोर्ट 8000 केवल localhost पर है और प्रॉक्सी के लिए तैयार है: जब आप दूसरी सर्विस जोड़ें तो Traefik के पीछे कई ऐप्स चलाना देखें।

सर्वर की .env में COMPOSE_FILE=compose.yaml:compose.prod.yaml सेट करें और आपके बाकी कमांड्स वापस साधारण docker compose logs -f app हो जाएंगे।

एक सिंगल-सर्विस स्टैक भी इसी तरह का आकार लेता है, क्योंकि एक सेल्फ-होस्टेड openGym वर्कआउट ट्रैकर को पहला पासकी एनरोल करने से पहले प्रॉक्सी के पीछे TLS पर रिस्पॉन्स देना होता है। एक बेस फाइल जिसमें कोई ports न हो, वही वह चीज है जो किसी अनचाहे पब्लिक बाइंडिंग को प्रॉक्सी से पहले काम शुरू करने से रोकती है।

डिप्लॉय करने से पहले merged model को पढ़ें

docker compose config पूरी तरह से merged और interpolated model को प्रिंट करता है। यह कोई preview नहीं है। यह वह सटीक input है जिस पर Compose कार्य करेगा, इसलिए जब output आपकी अपेक्षाओं से मेल न खाए, तो output ही सही है।

docker compose -f compose.yaml -f compose.prod.yaml config
docker compose -f compose.yaml -f compose.prod.yaml config --no-interpolate
docker compose -f compose.yaml -f compose.prod.yaml config --services

--no-interpolate, ${VAR} को unexpanded छोड़ देता है। इसे कहीं भी output paste करने से पहले उपयोग करें, क्योंकि साधारण config हर resolved secret को clear text में प्रिंट करता है। --services केवल service के नाम सूचीबद्ध करता है, जो यह पुष्टि करने का एक त्वरित तरीका है कि include ने वही pull किया है जिसकी आपको अपेक्षा थी।

विफलता के प्रकार और आप क्या देखेंगे

no configuration file provided: not found. Compose को पढ़ने के लिए कुछ नहीं मिला। आप प्रोजेक्ट डायरेक्टरी से बाहर हैं, या COMPOSE_FILE एक ऐसे पाथ का नाम है जो मौजूद नहीं है। Compose डिफ़ॉल्ट बेस फ़ाइल के लिए पैरेंट डायरेक्टरीज़ में खोज करता है, लेकिन आपके द्वारा स्वयं नामित फ़ाइल के लिए यह कहीं भी खोज नहीं करता है।

WARN[0000] The "POSTGRES_PASSWORD" variable is not set. Defaulting to a blank string. इंटरपोलेशन प्रोजेक्ट की .env फ़ाइल और शेल एनवायरनमेंट के आधार पर रिज़ॉल्व होता है, और यहाँ प्रोजेक्ट डायरेक्टरी वह डायरेक्टरी है जहाँ पहली -f फ़ाइल स्थित है। .env वाली डायरेक्टरी से अलग किसी अन्य डायरेक्टरी से डिप्लॉय करने पर आपको यह चेतावनी मिलती है और उसके बाद एक ऐसा डेटाबेस मिलता है जो हर कनेक्शन को अस्वीकार कर देता है।

आपका ओवरराइड एडिट docker compose config में दिखाई नहीं दे रहा है। या तो आपने -f पास किया है, जो ऑटोमैटिक ओवरराइड लोडिंग को बंद कर देता है, या Compose को पैरेंट डायरेक्टरी में compose.yaml मिल गया है और आपकी ओवरराइड फ़ाइल उसके बगल में नहीं है। बिना किसी अन्य तर्क के docker compose config चलाने पर आपको पता चल जाएगा कि Compose वास्तव में कौन सा मॉडल बना रहा है।

एक बाइंड माउंट खाली है और Docker ने एक ऐसी डायरेक्टरी बना दी है जिसे आपने नहीं मांगा था। रिलेटिव पाथ पहली फ़ाइल की डायरेक्टरी के आधार पर रिज़ॉल्व हुआ। पाथ को ठीक करें, --project-directory पास करें, या फ्रैगमेंट को include के पीछे ले जाएं।

कंटेनर नए नामों के साथ वापस आते हैं और एक वॉल्यूम खाली दिखता है। प्रोजेक्ट का नाम बदल गया है, क्योंकि प्रोजेक्ट का नाम पहली फ़ाइल की डायरेक्टरी का अनुसरण करता है। बेस फ़ाइल में एक टॉप-लेवल name: जोड़ें और नाम बदलना बंद हो जाएगा। पुराना वॉल्यूम अभी भी पुराने प्रीफ़िक्स के तहत मौजूद है, और docker volume ls इसे दिखाएगा।

ओवरराइड में आपके द्वारा हटाया गया पोर्ट अभी भी खुला है। ports मर्ज ने बदलने के बजाय उसे जोड़ दिया (append कर दिया)। docker compose config के साथ पुष्टि करें, फिर या तो !override का उपयोग करें या ports को बेस फ़ाइल से बाहर ले जाएं।

FAQ

क्या Compose अपने आप compose.override.yaml को लोड करता है?

हाँ, जब आप बिना किसी -f फ्लैग के docker compose चलाते हैं। Compose वर्किंग डायरेक्टरी और उसके पैरेंट डायरेक्टरी में compose.yaml या docker-compose.yaml को खोजता है, और यदि उसके बगल में कोई ओवरराइड फ़ाइल मौजूद हो, तो वह फ़ाइल दूसरी बार लोड की जाती है। पहचाने जाने वाले नाम compose.override.yaml, compose.override.yml, docker-compose.override.yml और docker-compose.override.yaml हैं। कोई भी -f पास करने से यह सुविधा बंद हो जाती है, इसलिए docker compose -f compose.yaml up केवल एक ही फ़ाइल पढ़ता है।

कई -f फ़ाइलें किस क्रम में मर्ज होती हैं?

बाएँ से दाएँ। Compose आपके द्वारा दी गई फ़ाइलों के क्रम में कॉन्फ़िगरेशन बनाता है, और प्रत्येक फ़ाइल अपने से पहले वाली फ़ाइलों को ओवरराइड करती है और उनमें जुड़ती है, इसलिए किसी भी टकराव की स्थिति में लाइन में मौजूद अंतिम फ़ाइल प्रभावी होती है। उस प्रोजेक्ट के हर कमांड के लिए एक ही सूची का उपयोग किया जाना चाहिए, जिसके लिए COMPOSE_FILE=compose.yaml:compose.prod.yaml का उपयोग होता है।

ओवरराइड करने के बाद भी मेरा पोर्ट पब्लिश क्यों है?

क्योंकि ports प्रविष्टियों की पहचान ip, target, published और protocol के पूरे सेट द्वारा की जाती है। बेस 8080:80 के मुकाबले 127.0.0.1:8080:80 का ओवरराइड ip भाग में भिन्न है, इसलिए Compose इसे दूसरे पोर्ट के रूप में मानता है और दोनों को रखता है। docker compose config चलाएँ और आपको दोनों प्रविष्टियाँ दिखाई देंगी। Compose v2.24.4 या नए वर्ज़न पर ports: !override का उपयोग करें, या बेस फ़ाइल से ports को हटा दें ताकि मर्ज करने के लिए कुछ भी न रहे।

include और -f के बीच क्या अंतर है?

-f एक ही एप्लिकेशन पर कई फ़ाइलों की परतें चढ़ाता है, और हर फ़ाइल में मौजूद प्रत्येक रिलेटिव पाथ पहली फ़ाइल की डायरेक्टरी के आधार पर रिज़ॉल्व होता है। include एक अलग Compose एप्लिकेशन को खींचता है, और प्रत्येक शामिल पाथ अपनी प्रोजेक्ट डायरेक्टरी को बनाए रखता है, इसलिए इसके रिलेटिव पाथ खुद के आधार पर रिज़ॉल्व होते हैं। अपने स्टैक की एनवायरनमेंट लेयर्स के लिए -f का उपयोग करें, और कहीं और मेंटेन किए गए फ्रैगमेंट के लिए include का उपयोग करें। include के लिए Compose v2.20.0 या नया वर्ज़न चाहिए।

मैं बेस फ़ाइल द्वारा सेट किए गए मान को कैसे हटाऊँ?

Compose v2.18.0 या नए वर्ज़न पर !reset टैग का उपयोग करें। ओवरराइडिंग फ़ाइल में ports: !reset [] या MY_VAR: !reset null लिखें और एट्रिब्यूट अपने डिफ़ॉल्ट मान पर या null पर वापस चला जाएगा। टैग को दिया गया मान आवश्यक है लेकिन उसे अनदेखा कर दिया जाता है। यदि आप किसी एट्रिब्यूट को क्लियर करने के बजाय बदलना चाहते हैं, तो !override ऐसा करता है, और इसके लिए v2.24.4 या नया वर्ज़न आवश्यक है।

क्या यह लेख उपयोगी था?