Jinsi ya kutumia faili nyingi za Docker Compose
Jifunze jinsi Docker Compose inavyounganisha faili za YAML, mpangilio sahihi wa faili, na jinsi ya kutumia include kwa mazingira ya dev na prod bila kukwama kwenye ports.
Jinsi Compose inavyofanya kazi na faili zaidi ya moja
Docker Compose inaweza kujenga mradi mmoja kutoka kwa faili kadhaa. Inazisoma kwa mpangilio inapozipokea na kuziunganisha kuwa modeli moja, hivyo faili inayokuja baadaye inashinda kwenye thamani yoyote inayokinzana. Mifumo miwili hufanya hivi kutoka kwa mstari wa amri: faili ya kubatilisha (override file) ambayo Compose huipakia yenyewe, na bendera ya -f unayopitisha kwa mkono. Mfumo wa tatu upo ndani ya faili yenyewe, kipengele cha include, na hufanya kazi tofauti na mifumo yote miwili.
Uunganishaji huu si uandikaji upya wa kawaida. Ramani (mappings) huunganishwa ufunguo kwa ufunguo, mfuatano (sequences) huongezewa, na seti ndogo ya sehemu hubadilishwa kikamilifu. Tofauti hiyo ndiyo chanzo cha mshangao, na orodha ya ports ndiyo inayomtatiza karibu kila mtu.
Kila kitu hapa chini kinachukulia kuwa unatumia Compose v2, programu-jalizi ya docker compose badala ya hati ya zamani ya docker-compose. Tekeleza docker compose version ili kuhakiki. Ikiwa bado hujaandika faili ya Compose, anza na mwongozo wa misingi ya Docker Compose kisha urudi hapa.
Faili la uingiliano (override) ambalo Compose hupakia bila kuambiwa
Tekeleza docker compose up bila kutumia bendera ya -f na Compose itatafuta katika saraka ya sasa, kisha saraka kuu zake, kwa ajili ya compose.yaml au docker-compose.yaml. Ikiwa faili la uingiliano lipo karibu na faili la msingi, Compose hulipakia hilo la pili, peke yake.
ls compose.yaml compose.override.yaml
docker compose up -dPindi faili zote mbili zinapokuwepo, hiyo ni sawa na kuziandika kwa mkono.
docker compose -f compose.yaml -f compose.override.yaml up -dMajina ambayo Compose huyatambua ni compose.override.yaml, compose.override.yml, na majina ya zamani ya docker-compose.override.yml na docker-compose.override.yaml. Jina lolote lingine, kwa mfano compose.dev.yaml, hupakiwa tu pale unapolitaja kwa kutumia -f.
Wakati unapopitisha -f moja, upakiaji wa kiotomatiki husimama. docker compose -f compose.yaml up husoma faili hilo moja pekee na kupuuza uingiliano, ambayo ndiyo sifa ambayo muundo wa dev na prod katika mwongozo huu umejengwa juu yake.
Hii ina pande mbili kwenye seva. Faili la uingiliano lililoachwa kwenye saraka ya deploy hupakiwa na kila amri ya docker compose inayotekelezwa kutoka saraka hiyo, ikijumuisha ile inayotekelezwa na cron job yako. Hivyo ndivyo rundo la uzalishaji (production stack) linavyoweza kuishia kuunganisha (bind-mount) saraka ya chanzo ambayo hakuna aliyekusudia kuitoa. Tekeleza docker compose config baada ya kila deploy na usome matokeo yake.
Kupanga kwa kutumia -f, na mahali ambapo njia za kadiri (relative paths) zinapoelekeza
Compose hujenga usanidi kwa mpangilio unaotoa faili, na faili zinazofuata hubatilisha na kuongezea zile zilizotangulia. Kutoka kushoto kwenda kulia, faili ya mwisho ndiyo inayoshinda.
docker compose -f compose.yaml -f compose.prod.yaml config
docker compose -f compose.yaml -f compose.prod.yaml up -dKila amri katika mradi huo inahitaji orodha sawa ya faili. Endesha up na faili mbili na logs na faili moja, na utakuwa unawasiliana na modeli tofauti iliyounganishwa, ambayo ni njia ya haraka ya kupata huduma ambayo Compose inasema haipo. Badala yake, weka orodha hiyo mara moja, kwa kutumia kigezo cha mazingira cha COMPOSE_FILE.
export COMPOSE_FILE=compose.yaml:compose.prod.yaml
docker compose config
docker compose up -dKitenganishi ni : kwenye Linux, na COMPOSE_PATH_SEPARATOR hukibadilisha. COMPOSE_FILE inaweza pia kuwekwa kwenye faili ya .env ya mradi, jambo ambalo huifanya kuwa sehemu ya mradi uliopakuliwa (checkout) badala ya kuwa sehemu ya historia ya shell yako. Kitu chochote kilichowekwa wazi kwenye mstari wa amri (command line) hupita kigezo cha mazingira.
Sasa, kanuni inayovunja bind mounts. Unapotumia faili nyingi na -f, njia zote za kadiri katika faili hizo zote huelekeza kwenye saraka ya faili ya kwanza, si kwenye faili inayozishikilia. Andika ./data:/var/lib/postgresql/data ndani ya deploy/prod/compose.prod.yaml na Compose bado itatafuta ./data karibu na faili ya msingi. Docker kisha hutengeneza saraka tupu kwenye njia hiyo isiyo sahihi na kontena huanza bila kitu ndani yake, jambo ambalo huonekana kama kupoteza data, lakini si hivyo. Pitisha --project-directory ili kuweka njia ya msingi wewe mwenyewe, au tumia include, ambayo huelekeza kila faili kwenye saraka yake yenyewe.
Jina la mradi hutoka kwenye saraka hiyo hiyo ya msingi, kwa hivyo kubadilisha faili ipi ni ya kwanza kunaweza kubadilisha jina la mradi. Mradi uliobadilishwa jina unamaanisha majina mapya ya kontena na majina mapya ya volumu, na volumu ya zamani bado iko kwenye diski chini ya jina la zamani. Ibandike badala yake kwa kutumia name: ya ngazi ya juu katika faili ya msingi.
name: myappNi sehemu zipi huunganishwa, na zipi hubadilishwa
Compose huunganisha kulingana na aina ya thamani, si kulingana na jina la sehemu.
- Sehemu zenye thamani moja hubadilishwa.
image,command,entrypointnamem_limithuchukua thamani ya baadaye moja kwa moja. Huwezi kuongeza hoja moja kwenyecommand, kwa sababu ubatilishaji huandika upya mstari mzima. - Ramani huunganishwa ufunguo kwa ufunguo.
environment,labels,volumesnadeviceshuhifadhi kila ufunguo kutoka kwenye faili zote mbili, na faili ya baadaye hushinda kwenye ufunguo wowote uliopo katika zote mbili. Kwaenvironmentnalabelsufunguo ni jina la kigeu au lebo. Kwavolumesnadevicesufunguo ni njia ya kontena. - Mfuatano huongezewa.
dns,dns_search,expose,tmpfsnaexternal_linkshuunganishwa. Msingi ulio naexpose: ["3000"]ukijumuishwa na ubatilishaji ulio na["4000", "5000"]hutoa["3000", "4000", "5000"].
Mfuatano minne hubeba ufunguo wa utambulisho, kwa hivyo viingizo vinavyolingana kwenye ufunguo huo huunganishwa badala ya kuongezewa. volumes, secrets na configs hulingana kwenye target. ports hulingana kwenye mchanganyiko wa ip, target, published na protocol.
Soma kanuni hiyo ya ports mara mbili, kwa sababu ndiyo mtego. Viingizo viwili vya bandari ni viingizo sawa tu wakati sehemu zote nne hizo zinakubaliana. Badilisha yoyote kati yao na Compose itaona bandari ya pili, isiyohusiana, kwa hivyo itahifadhi zote mbili.
Kwa nini mlango wako bado umechapishwa baada ya kuubatilisha
Faili ya msingi inayochapisha huduma kwenye kila kiolesura:
services:
web:
image: nginx:1.27
ports:
- "8080:80"Ubatilishaji ulioandikwa ili kuufunga kwenye localhost pekee, kwa sababu proksi ya nyuma (reverse proxy) itakaa mbele yake:
services:
web:
ports:
- "127.0.0.1:8080:80"Kagua matokeo kabla ya kudhani kuwa imefanya kazi.
docker compose -f compose.yaml -f compose.prod.yaml configIngizo zote mbili zimo kwenye matokeo. Sehemu ya ip inatofautiana, 0.0.0.0 dhidi ya 127.0.0.1, kwa hivyo hiyo ni milango miwili tofauti kwa kadiri ya muunganiko unavyohusika, na ufungaji wa umma uliotaka kuondoa bado umo kwenye modeli. Hilo ni muhimu zaidi kwenye Docker kuliko kwingineko, kwa sababu mlango uliochapishwa huandikwa kwenye iptables kabla ya kanuni zako za ngome (firewall). Utaratibu huu unafafanuliwa katika kwa nini milango ya Docker iliyochapishwa hupita ufw.
Kuna marekebisho mawili. Lile la wazi ni lebo ya !override, ambayo hubadilisha sifa nzima na kuruka kanuni za muunganiko:
services:
web:
ports: !override
- "127.0.0.1:8080:80"!override inahitaji Compose v2.24.4 au mpya zaidi. Marekebisho yanayoweza kubebeka hayahitaji lebo yoyote: acha ports nje ya faili ya msingi kabisa na uitangaze kwenye faili mahususi za mazingira pekee. Hakuna cha kuunganishwa inamaanisha hakuna cha kuvuja. Huo ndio muundo unaotumiwa katika mfano wa kazi hapa chini.
Kufuta thamani kutoka kwenye faili ya msingi
!reset huondoa sifa, na kuirejesha kwenye thamani yake ya awali au kuifanya kuwa null. Inachukua thamani na kuipuuza, kwa hivyo andika kitu chochote kilicho sahihi na tupu.
services:
web:
ports: !reset []
environment:
DEBUG: !reset null!reset inahitaji Compose v2.24 au toleo jipya zaidi. Itumie wakati faili ya msingi si yako ya kuhariri, kwa mfano, kipande cha faili kutoka kwa mtoa huduma unachokiingiza.
include, kwa ajili ya stack zilizokusanywa kutoka sehemu mbalimbali
include huleta programu nyingine ya Compose kwenye modeli yako. Hiki ni kipengele cha ngazi ya juu, si bendera (flag).
include:
- path: ../commons/compose.yamlKila njia (path) katika include hupakiwa kama modeli yake yenyewe ya programu ya Compose, ikiwa na saraka yake ya mradi, kwa hivyo njia za kirejeleo (relative paths) ndani ya faili hiyo hutatuliwa kulingana na saraka ya faili hiyo yenyewe. Hiyo ndiyo tofauti halisi kutoka kwa -f, na ndiyo sababu include ni zana sahihi wakati sehemu hiyo (fragment) inapoishi katika folda nyingine au hazina (repository) nyingine.
Muundo mrefu huchukua chaguzi ndogo.
include:
- path:
- ../monitoring/compose.yaml
- ../monitoring/compose.vps.yaml
project_directory: ../monitoring
env_file: ../monitoring/.envpath hukubali orodha, na faili hizo huunganishwa pamoja kwa kutumia kanuni za kawaida kabla ya matokeo kujiunga na modeli yako. project_directory huweka njia ya msingi inayotumiwa kutatua njia za kirejeleo katika faili iliyojumuishwa. env_file huipa faili iliyojumuishwa vigezo vyake (variables) vya uingizaji (interpolation), jambo ambalo huzuia sehemu iliyoshirikiwa kusoma kimyakimya .env ya mradi wako. include inahitaji Compose v2.20.0 au mpya zaidi.
Majina ya rasilimali yanayojirudia kati ya faili yako na faili iliyojumuishwa huripotiwa kama hitilafu badala ya kuunganishwa kimyakimya, na hilo ni la makusudi. Ili kubadilisha kitu ambacho faili iliyojumuishwa imetangaza, weka mabadiliko hayo katika compose.override.yaml: ubatilishaji (override) hutumika kwenye modeli iliyokusanywa, kwa hivyo inaweza kugusa rasilimali zilizojumuishwa bila kugongana nazo.
Muhtasari: include huunganisha programu tofauti, -f huweka usanidi juu ya programu moja.
Mgawanyo wa mazingira ya dev na prod kwenye VPS moja
Huu hapa ni muundo mzima katika faili tatu. Faili ya msingi inatangaza kile ambacho ni kweli kila mahali, na haichapishi bandari yoyote.
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:Sharti la depends_on ndilo linalofanya programu kusubiri hifadhidata inayojibu badala ya kontena lililopo tu, kama ilivyoelezwa katika healthchecks na masharti ya depends_on. POSTGRES_PASSWORD inachukuliwa kutoka kwenye faili ya .env ya mradi, ambayo haipaswi kamwe kuwekwa kwenye git. Tazama faili za env na siri za Compose kwa njia salama zaidi.
Inayofuata ni compose.override.yaml, ambayo Compose huipakia yenyewe. Hii ni faili ya msanidi programu.
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"Kwenye kompyuta ya mkononi, amri ya kawaida ya docker compose up huunganisha faili hizo mbili. command inachukua nafasi ya thamani chaguo-msingi ya image kwa sababu ina thamani moja tu. LOG_LEVEL inachukua nafasi ya info kwa sababu environment huunganisha kwa kutumia ufunguo. Bind mount na bandari mbili zilizochapishwa ni nyongeza tu, na bandari ya hifadhidata imefungwa kwenye localhost ili kompyuta iliyo kwenye mtandao wa pamoja isitoe PostgreSQL kwa wengine waliopo chumbani.
Mwisho, compose.prod.yaml. Jina lake si lile ambalo Compose hutafuta, kwa hivyo halipakii kwa bahati mbaya.
services:
app:
ports:
- "127.0.0.1:8000:3000"
deploy:
resources:
limits:
memory: 512MKwenye VPS unataja faili zote mbili, na kitendo hicho cha kuzitaja ndicho kinachozuia faili ya override isitumike.
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 psps inapaswa kuorodhesha huduma zote mbili zikiwa zinafanya kazi, huku db ikionyesha (healthy). Kwa sababu umepitisha -f, compose.override.yaml haikusomwa, kwa hivyo amri ya dev, bind mount ya chanzo na bandari ya umma 3000 haziwezi kufikia uzalishaji (production) ingawa faili ipo kwenye saraka hiyo hiyo. Bandari 8000 iko kwenye localhost pekee, ikiwa tayari kwa proksi: tazama kuendesha programu kadhaa nyuma ya Traefik unapoongeza huduma ya pili.
Weka COMPOSE_FILE=compose.yaml:compose.prod.yaml katika .env ya seva na amri zako nyingine zitarudi kuwa docker compose logs -f app ya kawaida.
Soma muundo uliounganishwa kabla ya kuupeleka
docker compose config huchapisha muundo uliounganishwa kikamilifu na uliokamilishwa kwa njia ya interpolation. Hii si hakikisho. Ni ingizo kamili ambalo Compose itafanyia kazi, kwa hivyo matokeo yanapokinzana na matarajio yako, matokeo ndiyo sahihi.
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 huacha ${VAR} bila kupanuliwa. Itumie kabla ya kubandika matokeo popote, kwa sababu config ya kawaida huchapisha kila siri iliyotatuliwa kwa maandishi wazi. --services huorodhesha majina ya huduma pekee, ambayo ni njia ya haraka ya kuthibitisha kuwa include imevuta ulichotarajia.
Aina za hitilafu, na utakachokiona
no configuration file provided: not found. Compose haikupata chochote cha kusoma. Upo nje ya saraka ya mradi, au COMPOSE_FILE inataja njia ambayo haipo. Compose hutafuta saraka kuu kwa ajili ya faili ya msingi chaguo-msingi, lakini haitafuti popote faili uliyoiita wewe mwenyewe.
WARN[0000] The "POSTGRES_PASSWORD" variable is not set. Defaulting to a blank string. Uingizaji wa data (interpolation) hutatuliwa dhidi ya faili ya .env ya mradi na mazingira ya shell, na saraka ya mradi hapa ni saraka ya faili ya kwanza ya -f. Kupeleka (deploying) kutoka saraka tofauti na ile iliyo na .env hukupa onyo hili na kisha hifadhidata inayokataa kila muunganisho.
Uhariri wako wa kubatilisha (override) hauonekani katika docker compose config. Aidha umepitisha -f, ambayo huzima upakiaji wa kiotomatiki wa ubatilishaji, au Compose ilipata compose.yaml katika saraka kuu na faili yako ya ubatilishaji haipo karibu nayo. Kuendesha docker compose config bila hoja nyingine yoyote hukuambia ni modeli gani Compose inajenga kweli.
Mlima wa kuunganisha (bind mount) ni tupu na Docker ilitengeneza saraka ambayo hukuomba. Njia ya jamaa (relative path) ilitatuliwa dhidi ya saraka ya faili ya kwanza. Rekebisha njia hiyo, pitisha --project-directory, au hamisha kipande hicho nyuma ya include.
Vyombo (containers) vinarudi na majina mapya na sauti (volume) inaonekana tupu. Jina la mradi limebadilika, kwa sababu jina la mradi hufuata saraka ya faili ya kwanza. Ongeza name: ya kiwango cha juu kwenye faili ya msingi na utoaji majina utaacha kuhama. Sauti ya zamani bado ipo chini ya kiambishi awali cha zamani, na docker volume ls itakuonyesha.
Lango (port) uliloliondoa katika ubatilishaji bado liko wazi. Muunganisho wa ports uliambatanisha badala ya kuchukua nafasi. Thibitisha na docker compose config, kisha tumia !override au hamisha ports nje ya faili ya msingi.
FAQ
Je, Compose hupakia compose.override.yaml kiotomatiki?
Ndiyo, unapoendesha docker compose bila kutumia bendera ya -f. Compose hutafuta saraka ya sasa na saraka mama kwa ajili ya compose.yaml au docker-compose.yaml, na ikiwa faili ya kubatilisha (override file) ipo kando yake, faili hiyo hupakiwa ya pili. Majina yanayotambulika ni compose.override.yaml, compose.override.yml, docker-compose.override.yml na docker-compose.override.yaml. Kupitisha -f yoyote huzima utaratibu huu, kwa hivyo docker compose -f compose.yaml up husoma faili moja pekee.
Faili nyingi za -f huunganishwa kwa mpangilio upi?
Kutoka kushoto kwenda kulia. Compose hujenga usanidi kwa mpangilio unaotoa faili hizo, na kila faili hubatilisha na kuongezea zile zilizotangulia, kwa hivyo faili ya mwisho kwenye mstari ndiyo inayoshinda katika mgongano wowote. Orodha ileile lazima itumike kwa kila amri katika mradi huo, jambo ambalo ndilo kusudi la COMPOSE_FILE=compose.yaml:compose.prod.yaml.
Kwa nini mlango wangu bado umechapishwa baada ya kuubatilisha?
Kwa sababu viingilio vya ports hutambuliwa na seti nzima ya ip, target, published na protocol. Ubatilishaji wa 127.0.0.1:8080:80 dhidi ya msingi wa 8080:80 hutofautiana katika sehemu ya ip, kwa hivyo Compose huichukulia kama mlango wa pili na kuhifadhi zote mbili. Endesha docker compose config na utaona viingilio hivyo viwili. Tumia ports: !override kwenye Compose v2.24.4 au mpya zaidi, au uweke ports nje ya faili ya msingi ili kusiwe na kitu cha kuunganishwa nacho.
Kuna tofauti gani kati ya include na -f?
-f huweka faili kadhaa juu ya programu moja, na kila njia ya kadiri (relative path) katika kila faili hutatuliwa dhidi ya saraka ya faili ya kwanza. include huleta programu tofauti ya Compose, na kila njia iliyojumuishwa huhifadhi saraka yake ya mradi, kwa hivyo njia zake za kadiri hutatuliwa dhidi yake yenyewe. Tumia -f kwa matabaka ya mazingira ya rundo lako mwenyewe, na include kwa sehemu inayodumishwa mahali pengine. include inahitaji Compose v2.20.0 au mpya zaidi.
Ninaondoaje thamani iliyowekwa na faili ya msingi?
Tumia lebo ya !reset kwenye Compose v2.24 au mpya zaidi. Andika ports: !reset [] au MY_VAR: !reset null katika faili ya kubatilisha na sifa hiyo itarudi kwenye thamani yake ya awali au kuwa null. Thamani unayoiweka kwenye lebo hiyo inahitajika lakini hupuuzwa. Ikiwa unataka kubadilisha sifa badala ya kuifuta, !override hufanya hivyo, na inahitaji v2.24.4 au mpya zaidi.