Docker Compose: Von der Entwicklung bis zur Produktion

Die Übersetzung der Podcasttranskription wurde im Vorfeld des Kursstarts vorbereitet. „Linux-Administrator“

Docker Compose: Von der Entwicklung bis zur Produktion

Docker Compose ist ein erstaunliches Tool zur Erstellung einer Arbeitsumgebung
für den Stack, der in Ihrer Anwendung verwendet wird. Es ermöglicht Ihnen,
jede Komponente Ihrer Anwendung mithilfe einer klaren und einfachen Syntax in YAML-
Dateien zu definieren.
.

Mit der Einführung von docker compose v3 können diese YAML-Dateien direkt in einer Produktionsumgebung verwendet werden, wenn Sie mit
einem Cluster Docker Swarm.

Aber bedeutet das, dass Sie dieselbe Docker-Compose-Datei sowohl im
Entwicklungsprozess als auch in der Produktionsumgebung verwenden können? Oder diese Datei auch für
Staging verwenden können? Nun, im Großen und Ganzen — ja, aber für diese Funktionalität benötigen wir Folgendes:

  • Variableninterpolation: Verwendung von Umgebungsvariablen für einige
    Werte, die in jeder Umgebung variieren.
  • Konfigurationsüberschreibung: Die Möglichkeit, eine zweite (oder jede
    andere nachfolgende) Docker-Compose-Datei zu definieren, die etwas im Vergleich
    zur ersten ändert, und Docker Compose erledigt das Zusammenführen beider Dateien.

Unterschiede zwischen Entwicklungs- und Produktionsdateien

Während der Entwicklung möchten Sie wahrscheinlich Codeänderungen in
Echtzeit überprüfen. Dazu wird normalerweise das Volume mit dem Quellcode in
den Container gemountet, der die Laufzeit für Ihre Anwendung enthält. Für die Produktionsumgebung
ist dieser Ansatz jedoch nicht geeignet.

In der Produktion haben Sie ein Cluster mit vielen Knoten, und das Volume ist lokal zum
Knoten, auf dem Ihr Container (oder Dienst) läuft. Daher können Sie den Quellcode nicht
einfach ohne komplizierte Operationen einbinden, die Code-Synchronisation, Signale usw.
beinhalten.

Stattdessen möchten wir in der Regel ein Image mit einer bestimmten Version Ihres Codes erstellen.
Dieses wird in der Regel mit einem entsprechenden Tag versehen (es kann semantische
Versionierung oder ein anderes System Ihrer Wahl verwendet werden).

Konfigurationsüberschreibung

Angesichts der Unterschiede und da Ihre Abhängigkeiten je nach
Entwicklungs- und Produktionsszenarien variieren können, ist klar, dass wir unterschiedliche

Konfigurationsdateien benötigen.
Docker Compose unterstützt das Zusammenführen verschiedener Compose-Dateien zur,

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

services:
  whale:
    image: docker/whalesay
    command: ["cowsay", "hello!"]
$ docker-compose up
Erstelle Netzwerk "composeconfigs_default" mit dem Standardtreiber
Starte composeconfigs_whale_1
Verbindung zu 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 beendet mit Code 0

Wie bereits erwähnt, unterstützt docker compose das Zusammenführen mehrerer Compose-
Dateien, wodurch es möglich ist, verschiedene Parameter im zweiten Datei zu überschreiben. Zum Beispiel:

$ 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
Erstelle composeconfigs_whale_1
Verbindung zu 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 beendet mit Code 0

Diese Syntax ist während der Entwicklung nicht sehr komfortabel, da der Befehl
häufig wiederholt ausgeführt werden muss.

Glücklicherweise sucht docker compose automatisch nach einer speziellen Datei mit dem Namen
docker-compose.override.yml um Werte zu überschreiben. docker-compose.yml. Wenn
Wenn Sie die zweite Datei umbenennen, erhalten Sie dasselbe Ergebnis, nur dass Sie den ursprünglichen Befehl verwenden:

$ mv docker-compose.second.yml docker-compose.override.yml
$ docker-compose up
Starte composeconfigs_whale_1
Verbindung zu 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 beendet mit Code 0

Das ist einfacher zu merken.

Variableninterpolation

Konfigurationsdateien unterstützen Interpoloation
von Variablen
und Standardwerten. Das heißt, Sie können Folgendes tun:

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

Und wenn Sie docker-compose build (oder push) ohne die Umgebungsvariable
$MY_SERVICE_VERSION, wird der Wert latest, verwendet, aber wenn Sie den Wert der Umgebungsvariable vor dem Build festlegen, wird er beim Build oder Push
in das Register
private.registry.mine Meine Prinzipien.

Meine Prinzipien

Methoden, die mir angenehm sind, können auch Ihnen nützlich sein. Ich folge diesen
einfachen Regeln:

  • Alle meine Stacks für Produktion, Entwicklung (oder andere Umgebungen) werden über
    docker-compose-Dateien definiert.
  • Die Konfigurationsdateien, die erforderlich sind, um alle meine Umgebungen abzudecken, vermeiden
    möglichst Duplikate.
  • Ich benötige einen einfachen Befehl, um in jeder Umgebung zu arbeiten.
  • Die Hauptkonfiguration wird in der Datei docker-compose.yml.
  • definiert. Umgebungsvariablen werden verwendet, um die Tags von Bildern oder anderen
    Variablen zu definieren, die sich von Umgebung zu Umgebung ändern können (Staging, Integration,
    Produktion).
  • Die Werte der Variablen für die Produktion werden als Standardwerte verwendet, um
    das Risiko zu minimieren, falls der Stack in der Produktion ohne
    definierte Umgebungsvariablen gestartet wird.
  • Um einen Dienst in der Produktionsumgebung zu starten, wird der Befehl docker stack deploy --compose-file docker-compose.yml --with-registry-auth my-stack-name.
  • Die Arbeitsumgebung wird mit dem Befehl gestartet docker-compose up -d.

Lassen Sie uns ein einfaches Beispiel ansehen.

# 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}
...

Und

# 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
...

Ich kann docker-compose (docker-compose up) verwenden,um den Stack im
Entwicklungsmodus mit dem Quellcode, der eingebunden ist, zu starten. /project/src.

Ich kann dieselben Dateien auch in der Produktion verwenden! Und ich könnte dieselbe
Datei docker-compose.yml für das Staging verwenden. Um dies in
Produktion bereitzustellen, muss ich nur das Image mit einem vordefinierten Tag
in der CI-Phase erstellen und pushen:

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

In der Produktion kann dies mit den folgenden Befehlen ausgeführt werden:

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

Und wenn Sie dasselbe im Staging machen möchten, müssen Sie einfach die
notwendigen Umgebungsvariablen für die Staging-Umgebung definieren:

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

So haben wir letztendlich zwei verschiedene docker-compose-Dateien verwendet, die ohne
Duplikationen von Konfigurationen für jede Ihrer Umgebungen verwendet werden können!

Erfahren Sie mehr über den Kurs „Linux-Administrator“

Quelle: habr.com

60GB SSD 8Gb DDR4