- Docker Compose lar deg definere og administrere flere containere fra én YAML-fil, noe som gjør det enklere å jobbe med mikrotjenestebaserte applikasjoner.
- Tjenestedelen er obligatorisk og fylles ut med nettverk, volumer, konfigurasjoner og hemmeligheter for å kontrollere kommunikasjon, persistens og konfigurasjon.
- Eksempler som Flask+Redis eller en fullstack-app med frontend, backend og database viser hvordan Compose forenkler utvikling og distribusjon.
- den kommandoer docker komponer opp, ned, ps og logger De danner den grunnleggende arbeidsflyten for løfting, feilsøking og stopping av stabler med containere.

Hvis du allerede har eksperimentert med containere og sett at for en "ekte" app trenger du mer enn én tjeneste som kjører samtidig (database, API, frontend, cache…), før eller siden vil du støte på Docker Compose. Dette verktøyet lar deg sette opp alt dette utstyret med én enkelt fil og et par kommandoer, uten å sjonglere terminaler og endeløse skript.
I denne veiledningen lærer du hva Docker Compose er og hvordan filen fungerer. compose.yaml og hvordan man orkestrerer applikasjoner Rene oppsett med flere containere: fra enkle eksempler med Flask og Redis til mer komplekse arkitekturer med frontend, backend og database. Du lærer også om nettverk, volumer, konfigurasjoner, hemmeligheter og de viktigste kommandoene for å jobbe komfortabelt i utviklingsmiljøer og mer krevende miljøer.
Hva er Docker Compose, og hvorfor er det verdt å bruke det?
Docker Compose er en Docker-utvidelse som tillater definere og administrere flere containere som om de var én enkelt applikasjon. I stedet for å starte hver tjeneste manuelt med dens «docker run» og parametere, beskriver du alt i en YAML-fil og starter det med én enkelt kommando.
Det fine med Compose er at mange moderne applikasjoner er bygget på den. mikrotjenester som bor i individuelle containereEn database, et API, et frontend, et køsystem, en Redis-lignende cache, osv. Docker anbefaler at hver container kjører én tjeneste, så hvis du prøver å få plass til alt i ett enkelt image, ender du opp med et monster som er vanskelig å skalere og vedlikeholde.
Du kan kjøre to eller flere tjenester i samme container, men Det opphever mange av Dockers fordeler.Hvis én feiler, drar den de andre ned; du kan ikke skalere bare den delen som får mest belastning, og det blir et stort rot å administrere logger, ressurser og feil.
Med Docker Compose definerer du hver tjeneste separat, og spesifiserer hvordan de kobler seg til hverandre, hvilke data de lagrer, hvilke porter de eksponerer, hvilke miljøvariabler de bruker ... På denne måten. Hvis én beholder svikter, kan resten fortsette å fungere. avhengig av hvordan du konfigurerer det, og skalering av et bestemt element er like enkelt som å endre innstillingene eller antall replikaer.
Dessuten passer Compose perfekt inn i arbeidsflyter hos CI/CD og distribusjon til produksjonDu kan bruke den direkte med verktøy som Portainer eller Docker Swarm, og hvis du jobber med Kubernetes, lar prosjekter som Kompose deg oversette en compose.yaml-fil til Kubernetes-manifester uten å måtte skrive alt om for hånd.
Forutsetninger for å følge Docker Compose-opplæringen
For å kunne følge eksemplene i denne veiledningen uten problemer trenger du ha Docker og Docker Compose installertI dag finnes det to hovedveier:
- Docker Engine + Docker Compose installert som frittstående binærfiler.
- DockerDesktop, som inkluderer Docker Engine, Docker Compose og et grafisk grensesnitt.
Det er viktig at du har et minimumsgrunnlag på grunnleggende Docker-kommandoer (bilder, containere, porter, volumer) og ikke vær redd for å bruke kommandolinjen. Eksemplene antas vanligvis i Linux (for eksempel Ubuntu 22.04), men logikken gjelder like mye i Windows og macOS med Docker Desktop.
Sjekk at alt er i orden ved å kjøre det på din terminal noe så enkelt som «docker –versjon» og «docker compose-versjon»Hvis begge kommandoene svarer uten feil, er du klar til å fortsette med eksemplene.
Grunnleggende struktur for en compose.yaml-fil
Hjertet i Docker Compose er filen compose.yaml (eller docker-compose.yml)Der beskriver vi hvilke tjenester vi ønsker å sette opp og hvordan de skal være relatert. Selv om feltet tidligere ble brukt version For å markere formatversjonen anbefaler gjeldende dokumentasjon at den ikke defineres, slik at den nyeste versjonen av skjemaet alltid brukes.
Innenfor Compose-filen vil du ha flere mulige seksjoner, men bare én er obligatorisk: tjenesterDerfra kan du legge til andre seksjoner avhengig av prosjektets kompleksitet:
- tjenesterdefinisjon av hver mikrotjeneste (obligatorisk).
- nettverk: tilpassede nettverk for å kontrollere kommunikasjon mellom containere.
- volumervolumer for å lagre data eller dele dem mellom tjenester.
- configstjenestekonfigurasjon (f.eks. konfigurasjonsfiler for webserver).
- hemmeligheterhåndtering av sensitiv informasjon (passord, API-nøkler…).
Gjennom denne veiledningen vil du se hvordan du kombinerer alle disse delene for et typisk prosjekt som inkluderer en applikasjon, en database og et APIog også et eksempel på en webapp i Python med Flask og Redis.
Tjenester i Docker Compose: kjernen i definisjonen
seksjon tjenester er den viktigste delen fra en hvilken som helst Compose-fil. I den definerer du hver av containerne som skal utgjøre applikasjonen din, og gir dem navnet du ønsker (for eksempel web, database, api, redis, Osv.).
For hver tjeneste kan du etablere et godt antall parametereBlant dem er noen som er mye brukt i virkelige prosjekter:
Parameter build indikerer hvor Dockerfilen befinner seg som tjenesteavbildningen skal bygges fra. Vanligvis spesifiseres en kontekst (katalog) der Dockerfilen til applikasjonen du vil pakke befinner seg.
Hvis du allerede har opprettet et bilde, eller ønsker å bruke et fra registeret, bruker du image å referere til detNavnet følger formatet [<registry>/][<project>/]<image>[:<tag>|@<digest>]Og hvis du trenger å kontrollere når bildet lastes ned eller oppdateres, kan du bruke pull_policy.
Felt ports Den brukes til å tilordne porter mellom verten og containerenSyntaksen er av typen [HOST:]CONTAINER[/PROTOCOL]Hvis for eksempel en PostgreSQL-database lytter på port 5432 inne i containeren, og du vil eksponere den på port 5555 på verten, gjør du noe slikt: "5555:5432" i listen over porter.
Omstartspolicyen styres med restartsom indikerer hva man skal gjøre når en container avsluttes feilaktig eller stopper. Typiske verdier er no, always, on-failure y unless-stoppedslik at kritiske tjenester kan forbli i drift selv om de opplever sporadiske driftsavbrudd.
Hvis én tjeneste trenger at en annen skal være tilgjengelig før den starter, kan du bruke depends_on å definere avhengigheter mellom containereEt klassisk eksempel er en app som krever at databasen er oppe og går for å unngå at den første tilkoblingen feiler.
For konfigurasjon og påloggingsinformasjon har du to vanlige tilnærminger: env_file y environment. Med env_file Du peker på én eller flere filer .env med miljøvariablene, mens i environment Du kan liste dem direkte i YAML. Det beste er å bruke filer. .env for å forhindre at passord og sensitive data legges inn i selve compose.yaml-filen.
Parameter volumes tillater montering av vertsbaner eller volumer Inne i containeren bruker du både datapersistens og mappedeling mellom tjenester. Her refererer du bare til volumene du senere kan definere i avsnittet ovenfor. volumes hvis du trenger at de deles eller administreres mer eksplisitt.
Med disse feltene kan du allerede bygge ganske komplette tjenester. Compose-spesifikasjonen inkluderer mange flere avanserte alternativer (helse, ressursgrenser, kommandoer fra bootosv.), men med disse dekker du allerede de vanligste bruksområdene.
Eksempel 1: Webapplikasjon i Python med Flask og Redis
Et typisk eksempel for å forstå Docker Compose er å lage en enkel webapplikasjon i PythonBruker Flask til å servere sider og Redis som et minnelager for en treffteller. Tanken er at du ikke trenger å installere verken Python eller Redis på maskinen din: alt kjører inne i containere.
Arbeidsflyten ville være omtrent slik: først oppretter du en katalog for prosjektet, og inni legger du til en fil app.py med Flask-koden. I den koden bruker du "redis" som vertsnavn og port 6379, som er standardporten for Redis-tjenesten i containeren din.
Funksjonen som administrerer besøkstelleren Den prøver å koble til Redis flere ganger. Før du gir opp, husk at det kan ta noen sekunder før Redis-containeren blir tilgjengelig når du løfter hele stakken.
Pluss app.py, du oppretter en fil requirements.txt med Python-avhengigheter (for eksempel Flask og redis-py), og en Dockerfile som spesifiserer hvordan du bygger webapplikasjonsimaget ditt: basis Python-image (3.7, 3.10 eller hva som helst), arbeidskatalog, miljøvariabler for Flask, gcc-installasjon og systemavhengigheter, kopi av requirements.txt, pakkeinstallasjon og kodekopi.
I Dockerfile markerer du også porten som vil vise containeren (for eksempel 5000) og du definerer standardkommandoen, vanligvis flask run --debug eller lignende, slik at den starter automatisk når containeren opprettes.
Med alt dette klart definerer compose.yaml-filen to tjenester: én som for eksempel heter web, som er bygget fra prosjektets Dockerfile og eksponerer port 8000 eksternt (tilordner vertens port 8000 til containerens port 5000), og en annen kalt redis que Hent det offisielle Redis-bildet fra Docker Hub.
For å starte applikasjonen, navigerer du bare til prosjektkatalogen og kjører "docker komponer opp"Compose tar seg av å laste ned Redis-imaget, bygge webapplikasjonsimaget og starte begge tjenestene i riktig rekkefølge.
Når det er oppe og går, går du inn i nettleseren din http://localhost:8000 (o http://127.0.0.1:8000) og du skal se en melding av typen «Hei verden» og en Besøksteller som øker hver gang du laster på nytt siden. Hvis du inspiserer de lokale bildene med docker image lsDu vil se noe sånt som redis y web opprettet eller lastet ned.
Når du vil stoppe alt, kan du gjøre det CTRL+C i terminalen der du forlot «docker compose up» eller utføre docker compose down fra prosjektkatalogen. Dette vil stoppe og fjerne containerne som ble opprettet av den komponeringen.
Forbedring av arbeidsflyt: Bind monteringer og Compose Watch
Det er mer praktisk å jobbe i utvikling med Docker hvis Du trenger ikke å rekonstruere bildet hver gang du berører koden. Det er her Bind Mounts og, i nyere versjoner, Docker Compose Watch kommer inn i bildet.
En Bind-montering innebærer å montere en mappe fra maskinen din inne i containeren. I compose.yaml-filen legger du til en seksjon i webtjenesten. volumes som tilordner prosjektkatalogen til arbeidskatalogen fra beholderen, for eksempel .:/codePå denne måten gjenspeiles eventuelle endringer du gjør i editoren umiddelbart i beholderen.
Hvis du også aktiverer Flasks feilsøkingsmodus med variabelen FLASK_DEBUG=1, kommandoen flask run Den vil automatisk laste inn programmet på nytt når det oppdager endringer i filene, uten at du trenger å stoppe og starte på nytt.
Docker Compose Watch tar det et skritt videre: du kan bruke «docker compose watch» eller «docker compose up –watch» Dette lar Compose overvåke prosjektfiler og synkronisere endringer med containere på en mer intelligent måte. Når du lagrer en fil, kopieres den til containeren, og utviklingsserveren oppdaterer applikasjonen uten å starte hele containeren på nytt.
Prøv for eksempel å endre velkomstmeldingen i app.py fra «Hallo verden!» til en setning som "Hilsen fra Docker"Lagre filen, oppdater nettleseren, så ser du den nye meldingen umiddelbart mens besøkstelleren fortsetter å kjøre uten å miste statusen sin.
Og når du er ferdig med å jobbe, kan du som alltid trekke docker compose down til slå av og rengjør beholderne som var i gang med den stabelen.
Eksempel 2: Fullstack-app med frontend, backend og database
For å se Docker Compose i en noe mer realistisk arkitektur, forestill deg en gjøremålsliste-applikasjon (Todo List) med et frontend i Vue.js, et API i Node.js og en MongoDB-database. Hver del ligger i sin egen katalog og har sin egen Dockerfile.
I arkivet kan du finne en mappe frontend med Vue-appen og en annen backend med Node-serveren. Bakenden eksponerer endepunkter for opprette, liste, oppdatere og slette oppgaverog kobler seg til MongoDB for å lagre dem. Frontend-systemet bruker disse endepunktene for å vise og administrere oppgavelisten i nettleseren.
Filen docker-compose.yml Den ligger i roten av prosjektet og definerer tre tjenester: frontend, backend y databaseFrontend-tjenesten bygges fra Dockerfile i den tilhørende mappen, og eksponeres vanligvis intern port 80 og tilordnes til port 5173 på verten (for eksempel for å bruke samme URL som i lokal utvikling).
Backend-en er bygget fra Dockerfilen i katalogen backend, eksponerer port 3000 (både inni og utenfor containeren, hvis du vil forenkle) og deklarerer en avhengighet av databasen for å sikre at MongoDB er tilgjengelig når den starter opp.
Tjenesten database bruk den direkte Offisielt bilde av MongoDB og bygge et volum, la oss si mongodb_dataPå /data/db, som er der Mongo lagrer dataene sine. Volumet er deklarert i den øverste delen. volumes fra compose, slik at dataene beholdes selv om du sletter og gjenskaper containerne.
Til slutt kobles alle disse tjenestene til via et tilpasset nettverk, for eksempel my-network, definert i seksjonen networksDette gjør at de kan løses etter tjenestenavn (backend kan koble til Mongo ved hjelp av vertsnavnet). database) og at trafikken er innkapslet i det isolerte nettverket.
Når konfigurasjonen er klar, kjør docker compose up I kjernen av prosjektet er det ansvarlig for bygg eller last ned bildene og start de tre containerneDu kan sjekke at alt er på plass med docker compose ps, og deretter tilgang til http://localhost:5173 for å se Vue-appen i nettleseren din og opprette dine første oppgaver.
Nettverk i Docker Compose: koble tjenester til hverandre
Nettverk er laget som tillater containerne dine De «ser» hverandre og snakker kontrollertSom standard oppretter Docker allerede nettverk for Compose, men å definere dem eksplisitt gir deg mer klarhet og kontroll over hva som kan kommunisere med hva.
Det fungerer enkelt: hver tjeneste inneholder et felt networks der du angir hvilke nettverk den tilhører, og deretter i den øverste delen networks Du definerer disse nettverkene med konfigurasjonen deres. Den vanligste (og anbefalte i mange tilfeller) tilnærmingen er å bruke driveren. bridge.
Et bronettverk skaper en privat plass nettverk for containerne dinemed automatisk DNS-oppløsning basert på tjenestenavnet. Det betyr at hvis for eksempel databasetjenesten din kalles databaseEnhver annen tjeneste på samme nettverk kan koble til ved hjelp av bare database som vertsnavn.
I et prosjekt med et frontend, en backend og en database, kan du for eksempel bestemme deg for å opprette et frontend-nettverk og et backend-nettverk. Frontend-en ville koble seg til backend-en, og backend-en til databasen, men frontend-en og databasen... De trenger ikke nødvendigvis å dele et nettverkreduserer det indre eksponerte overflatearealet.
I kode betyr dette noe så enkelt som å tilordne det tilsvarende nettverket til hver tjeneste, og deretter definere disse nettverkene med driverbroer. På applikasjonsnivå er den enkleste tilnærmingen å bruke tjenestenavnet som vert når du konfigurerer tilkoblinger: av app a databaseFor eksempel, ganske enkelt ved å angi at databaseverten er «database».
Volumer i Docker Compose: Datapersistens
Volum er den anbefalte måten å vedvarende informasjon generert av containerneSom databaserBrukerfiler, sikkerhetskopier osv. De brukes også til å dele data mellom tjenester innenfor samme stabel.
I seksjonen services Du kan montere volumer direkte med volumesMen når du vil at volumet skal være tilgjengelig for flere containere, eller du vil administrere det mer eksplisitt, definerer du det også i den øverste delen. volumes fra compose.yaml.
Tenk deg at du vil sette opp et sikkerhetskopieringssystem for databasen din. Da ville databasetjenesten montere et volum der den lagrer dataene sine, og en annen tjeneste dedikert til sikkerhetskopier som Monter det samme volumet i lesemodus for å utføre eksport eller synkronisering uten å berøre hovedbeholderen.
Docker lar deg finjustere konfigurasjonen av volumer med flere parametere (drivertype, spesifikke alternativer for drivere eksterne faktorer osv.), men i de fleste tilfeller er det mest praktiske å la det skje. Docker administrerer volumer automatisk uten å bli gal med rare konfigurasjoner.
Det viktigste er å være tydelig på hvilke mapper i tjenestene dine som må være persistente, og å deklarere dem som volumer i Compose, slik at du ikke mister data når du gjenskaper containere eller oppdaterer bilder.
Konfigurasjoner: administrere konfigurasjonsfiler
seksjon configs Den er designet for å administrere konfigurasjonsfiler av tjenester i stacken din, lik volumer, men spesifikt fokusert på konfigurasjon.
Tenk deg en Apache- eller Nginx-server som kjører på Docker. Du trenger sannsynligvis juster konfigurasjonsfilen din Å gjenoppbygge bildet hver gang du endrer disse filene er ineffektivt og irriterende, spesielt i miljøer der parametere justeres ofte.
med configs Du kan spesifisere i tjenesten du ønsker bruke en spesifikk konfigurasjon og beskriv det deretter i avsnittet configsDet finnes flere måter å definere dem på, den vanligste er:
fileKonfigurasjonen genereres fra en lokal fil.external: hvis den er merket somtrue`Compose` forutsetter at konfigurasjonen allerede finnes og kun refereres til.nameInternt navn på konfigurasjonen i Docker, nyttig når man kombinerer medexternal: true.
På denne måten kan du oppdatere konfigurasjonsfilen på maskinen din og gå tilbake til heve stakken uten å måtte gjenoppbygge basisbildet, og holder bildekoden atskilt fra den miljøspesifikke konfigurasjonen.
Hemmeligheter: legitimasjon og sensitive data
seksjon secrets løser et klassisk problemHvor lagrer jeg passord, API-nøkler og annen sensitiv informasjon uten å la dem ligge spredt i koden eller YAML?
Akkurat som med konfigurasjoner, kan hemmeligheter defineres på forskjellige måterDet vanlige er:
fileHemmeligheten genereres fra innholdet i en fil (for eksempel en tekstfil med en nøkkel).environmentHemmeligheten opprettes ved hjelp av verdien til en miljøvariabel på systemet ditt.external: indikerer at hemmeligheten allerede er opprettet og bare trenger å refereres til. Dette er nyttig for å unngå å overskrive hemmeligheter som administreres utenfra.name: internt navn på hemmeligheten, spesielt relevant ved kombinasjonexternal: truemed hemmeligheter laget av et annet verktøy.
Med hemmeligheter kan du lage containere som trenger tilgang til disse påloggingsinformasjonene les dem på en kontrollert måte uten at de må være synlige i kodelageret eller i selve compose.yaml-filen, noe som forsterker sikkerheten til implementeringene dine betydelig.
Arbeide med flere filer Komponer og inkluder
I store prosjekter er det ikke uvanlig at applikasjonen din er delt inn i flere tjenester, noen ganger administrert av forskjellige team. I slike tilfeller er det praktisk å... separer konfigurasjonen i flere Compose-filer for å bedre modularisere arkitekturen.
En typisk tilnærming er å ha en compose.yaml hovedfilen for applikasjonen og andre filer for deler av infrastrukturen. Du kan for eksempel flytt definisjonen av Redis eller andre filstøttetjenester infra.yaml og behold bare det som er direkte angående appen din i hovedinnlegget.
For å gjøre dette oppretter du filen infra.yaml med egen seksjon services hvor du for eksempel legger igjen hele Redis-tjenesten. Deretter, i din compose.yaml hoved, du legger til en seksjon include som peker til filen infra.yaml.
Når du løper docker compose up Fra prosjektkatalogen, Skriv Kombiner begge filene og den viser alle tjenestene som om de var i én YAML, men du har fortsatt logikken atskilt og mer organisert.
Denne teknikken gjør det enklere for ulike team å vedlikeholde sine egne Compose-filer og å sette sammen den globale applikasjonen ved hjelp av includes, noe som er veldig nyttig i arkitekturer med dusinvis av containere eller miljøer med mye delt infrastruktur.
Viktige Docker Compose-kommandoer
Selv om Compose har en god katalog med kommandoer, bruker de fleste i det daglige arbeidet en håndfull av dem på gjentakende basisDet er viktig å mestre dem fordi det er de som definerer arbeidsflyten din.
Det viktigste er docker compose upDenne kommandoen bygger de nødvendige avbildningene (hvis de ikke allerede finnes), oppretter containerne, konfigurerer nettverk og volumer, og starter alle tjenestene som er definert i Compose-filen din. Det er kommandoen du bruker når du vil starte stacken din.
Det er vanligvis kombinert med alternativet -d å kjøre den i "frakoblet" modusDet vil si i bakgrunnen. På denne måten fyller du ikke opp terminalen med logger, og du kan fortsette å bruke den økten til andre kommandoer. For eksempel: docker compose up -d.
For å stoppe og rydde opp i det du har løftet, bruker du docker compose downsom stopper og fjerner containere, nettverk og eventuelt tilknyttede bilder og volumer. To svært vanlige flagg her er --rmi (for å slette bilder) og -v (for å fjerne volumer definert i seksjonen volumes).
Hvis du vil se hvilke containere som er en del av prosjektet og hva statusen deres er, kan du kjøre docker compose psDenne lister opp hver tjeneste, statusen (oppe, avsluttet osv.) og de eksponerte portene, noe som er veldig nyttig for å bekrefte at alt fungerer som det skal etter en up.
Når du starter stakken din i frakoblet modus, vises ikke loggene i terminalen. For å se dem må du bruke... docker compose logsenten globalt eller ved filtrering etter tjeneste. Flagget -f Den lar deg spore logger i sanntid, veldig nyttig for feilsøke en spesifikk tjeneste uten å måtte få tilgang til innsiden av beholderen.
Typisk arbeidsflyt: definere compose.yaml, utfør en docker compose up -d, sjekk med docker compose ps, gjennomgå logger med docker compose logs -f <servicio> Hvis noe går galt, og når du er ferdig, bruk docker compose down å la alt være rent.
Hvis du noen gang går deg vill, docker compose --help Den viser deg listen over tilgjengelige underkommandoer og alternativer for å hjelpe deg med å huske hva hver ting gjør uten å måtte gå til dokumentasjonen.
I lys av alt det ovennevnte, nøkkelverktøy For alle som jobber med containere utover bare individuelle prosjekter, er Compose et flott verktøy. Det lar deg utvikle direkte i et miljø som er veldig likt (eller identisk med) produksjon, kontrolltjenester, nettverk og data fra en enkel YAML-fil, og unngå en rekke kompatibilitets- og distribusjonsproblemer som uunngåelig oppstår når man bare jobber "lokalt" uten containere. Når du først har blitt vant til å skrive en god Compose YAML-fil for prosjektene dine, er det vanskelig å gå tilbake.
Lidenskapelig forfatter om verden av bytes og teknologi generelt. Jeg elsker å dele kunnskapen min gjennom å skrive, og det er det jeg skal gjøre i denne bloggen, vise deg alle de mest interessante tingene om dingser, programvare, maskinvare, teknologiske trender og mer. Målet mitt er å hjelpe deg med å navigere i den digitale verden på en enkel og underholdende måte.
