Docker Compose: från utveckling till produktion

Översättningen av podkasttranskriptionen förbereds inför starten av kursen «Linuxadministratör»

Docker Compose: från utveckling till produktion

Docker Compose är ett fantastiskt verktyg för att skapa en arbetsmiljö
för stacken som används i din applikation. Det låter dig definiera
varje komponent av din applikation, enligt en tydlig och enkel syntax i YAML-
filer.
.

Med framkomsten av docker compose v3 kan dessa YAML-filer användas direkt i produktionsmiljön när du arbetar med
klustret. Docker Swarm.

Men betyder det att du kan använda samma docker-compose-fil i
utvecklingsprocessen och i produktionsmiljön? Eller använda samma fil för
staging? Ja, generellt sett — men för sådan funktionalitet behöver vi följande:

  • Variabel interpolering: användning av miljövariabler för vissa
    värden som ändras i varje miljö.
  • Överskrivning av konfiguration: möjligheten att definiera en andra (eller någon
    annan efterföljande) docker-compose-fil som ändrar något i förhållande till
    den första, och docker compose tar hand om sammanslagningen av båda filerna.

Skillnader mellan filer för utveckling och produktion

Under utvecklingen vill du förmodligen kontrollera kodförändringar i
real-tid. För detta monteras vanligtvis volymen med källkoden i
containern som har runtime för din applikation. Men för produktionsmiljö
är denna metod inte lämplig.

I produktionen har du ett kluster med många noder, och volymen är lokal i
förhållande till noden där din container (eller tjänst) körs, så du kan inte
montera källkoden utan komplexa operationer som innebär
kodsynkronisering, signaler etc.

Istället vill vi vanligtvis skapa en bild med en specifik version av din kod.
Denna brukar märkas med en passande tagg (du kan använda semantisk
versionering eller ett annat system efter eget val).

Överskrivning av konfiguration

Med hänsyn till skillnaderna och att dina beroenden kan skilja sig åt i scenarier
för utveckling och produktion, är det klart att vi behöver olika konfigurationsfiler.

Docker compose stöder sammanslagning av olika compose-filer för
att få den slutgiltiga konfigurationen. Hur detta fungerar kan ses i exemplet:

$ cat docker-compose.yml
version: "3.2"

services:
  whale:
    image: docker/whalesay
    command: ["cowsay", "hello!"]
$ docker-compose up
Creating network "composeconfigs_default" with the default driver
Starting composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1  |  ________
whale_1  | 
whale_1  |  --------
whale_1  |     
whale_1  |      
whale_1  |       
whale_1  |                     ##        .
whale_1  |               ## ## ##       ==
whale_1  |            ## ## ## ##      ===
whale_1  |        /""""""""""""""""___/ ===
whale_1  |   ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
whale_1  |        ______ o          __/
whale_1  |                     __/
whale_1  |           __________/
composeconfigs_whale_1 exited with code 0

Som sagt, docker compose stöder sammanslagning av flera compose-filer,
detta gör att man kan överskrida olika parametrar i den andra filen. Till exempel:

$ cat docker-compose.second.yml
version: "3.2"
services:
  whale:
    command: ["cowsay", "bye!"]

$ docker-compose -f docker-compose.yml -f docker-compose.second.yml up
Creating composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1  |  ______
whale_1  | 
whale_1  |  ------
whale_1  |     
whale_1  |      
whale_1  |       
whale_1  |                     ##        .
whale_1  |               ## ## ##       ==
whale_1  |            ## ## ## ##      ===
whale_1  |        /""""""""""""""""___/ ===
whale_1  |   ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
whale_1  |        ______ o          __/
whale_1  |                     __/
whale_1  |           __________/
composeconfigs_whale_1 exited with code 0

Denna syntax är inte särskilt bekväm under utveckling, när kommandot
måste köras flera gånger.

Som tur är, letar docker compose automatiskt efter en speciell fil med namnet
docker-compose.override.yml för att överskrida värden docker-compose.yml. Om
om du byter namn på den andra filen, får du samma resultat, men med det ursprungliga kommandot:

$ mv docker-compose.second.yml docker-compose.override.yml
$ docker-compose up
Starting composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1  |  ______
whale_1  | 
whale_1  |  ------
whale_1  |     
whale_1  |      
whale_1  |       
whale_1  |                     ##        .
whale_1  |               ## ## ##       ==
whale_1  |            ## ## ## ##      ===
whale_1  |        /""""""""""""""""___/ ===
whale_1  |   ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
whale_1  |        ______ o          __/
whale_1  |                     __/
whale_1  |           __________/
composeconfigs_whale_1 exited with code 0

Bra, det är enklare att komma ihåg.

Variabelinterpolering

Konfigurationsfiler stöder interpolering
av variabler
och standardvärden. Det betyder att du kan göra följande:

services:
  my-service:
    build:
      context: .
    image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
...

Och om du kör docker-compose build (eller push) utan miljövariabeln
$MY_SERVICE_VERSION, kommer värdet latest, att användas, men om du sätter
miljövariabelvärdet före byggnationen, kommer det att användas vid byggandet eller pushen
till registret private.registry.mine.

Mina principer

Metoder som passar mig kan också vara användbara för dig. Jag följer dessa
enkla regler:

  • Alla mina stackar för produktion, utveckling (eller andra miljöer) definieras genom
    docker-compose-filer.
  • Konfigurationsfilerna som behövs för att täcka alla mina miljöer undviker
    duplicering så mycket som möjligt.
  • Jag behöver ett enkelt kommando för att arbeta i varje miljö.
  • Huvudkonfigurationen definieras i filen docker-compose.yml.
  • Miljövariabler används för att definiera bildtaggar eller andra
    variabler som kan ändras från miljö till miljö (staging, integration,
    produktion).
  • Värdena för variablerna i produktionen används som standardvärden, detta
    minimerar riskerna om stacken körs i produktion utan
    inställda miljövariabler.
  • För att köra tjänsten i produktionsmiljön används kommandot docker stack deploy --compose-file docker-compose.yml --with-registry-auth my-stack-name.
  • Utvecklingsmiljön startas med kommandot docker-compose up -d.

Låt oss titta på ett enkelt exempel.

# docker-compose.yml
...
services:
  my-service:
    build:
      context: .
    image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
    environment:
      API_ENDPOINT: ${API_ENDPOINT:-https://production.my-api.com}
...

Och

# docker-compose.override.yml
...
services:
  my-service:
    ports: # This is needed for development!
      - 80:80
    environment:
      API_ENDPOINT: https://devel.my-api.com
    volumes:
      - ./:/project/src
...

Jag kan använda docker-compose (docker-compose up), för att starta stacken i
utvecklingsläge med källkoden monterad i /project/src.

Jag kan använda dessa samma filer i produktionen! Och jag skulle kunna använda exakt
samma fil docker-compose.yml för staging. För att distribuera detta till
produktion behöver jag bara bygga och skicka bilden med en fördefinierad tagg
under CI-stadiet:

export MY_SERVICE_VERSION=1.2.3
docker-compose -f docker-compose.yml build
docker-compose -f docker-compose.yml push

I produktionen kan detta köras med följande kommandon:

export MY_SERVICE_VERSION=1.2.3
docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-auth

Och om du vill göra samma sak på staging, behöver du bara definiera
de nödvändiga miljövariablerna för att fungera i staging-miljön:

export MY_SERVICE_VERSION=1.2.3
export API_ENDPOINT=http://staging.my-api.com
docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-auth

Som ett resultat använde vi två olika docker-compose-filer, som utan
duplicering av konfigurationer kan användas för vilken av dina miljöer som helst!

Läs mer om kursen «Linuxadministratör»

Källa: habr.com

Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar 🔥 Köp pålitlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster