Docker Compose: Von der Entwicklung bis zur Produktion

Die Übersetzung des Podcast-Transkripts wurde im Vorfeld des Kursstarts vorbereitet. „Linux-Administrator“

Docker Compose: Von der Entwicklung bis zur Produktion

Docker Compose ist ein bemerkenswertes Tool zur Erstellung einer Arbeitsumgebung
für den Stack, der in Ihrer Anwendung verwendet wird. Es ermöglicht Ihnen, jeden
Einzelbestandteil Ihrer Anwendung zu definieren, indem Sie einer klaren und einfachen Syntax in YAML-
Dateien folgen.
.

Mit dem Aufkommen von docker compose v3 können diese YAML-Dateien direkt in der Produktionsumgebung verwendet werden, wenn Sie mit
einem Cluster arbeiten. Docker Swarm.

Aber bedeutet das, dass Sie dieselbe docker-compose Datei sowohl im
Entwicklungsprozess als auch in der Produktionsumgebung verwenden können? Oder dasselbe Datei für
Staging verwenden? Nun, im Allgemeinen — ja, aber für diese Funktionalität benötigen wir Folgendes:

  • Variableninterpolation: die Verwendung von Umgebungsvariablen für einige
    Werte, die sich in jeder Umgebung ändern.
  • Konfigurationsüberschreibung: die Möglichkeit, eine zweite (oder eine beliebige
    andere nachfolgende) docker-compose Datei zu definieren, die etwas in Bezug auf
    die erste ändert, und docker compose kümmert sich um das Zusammenführen beider Dateien.

Unterschiede zwischen den Dateien für Entwicklung und Produktion

Während der Entwicklung möchten Sie wahrscheinlich Codeänderungen überprüfen in
Echtzeitbetrieb. Dazu wird normalerweise das Verzeichnis des Quellcodes in einen
Container gemountet, der die Laufzeitumgebung für Ihre Anwendung enthält. Für eine Produktionsumgebung
ist diese Methode jedoch nicht geeignet.

In der Produktion haben Sie ein Cluster mit vielen Knoten, wobei das Verzeichnis lokal für
den Knoten ist, auf dem Ihr Container (oder Dienst) läuft. Daher können Sie den
Quellcode nicht ohne komplexe Operationen mounten, die Synchronisation von Code, Signalen usw. beinhalten.
Stattdessen möchten wir in der Regel ein Image mit einer bestimmten Version Ihres Codes erstellen.

Dieses wird üblicherweise mit einem entsprechenden Tag versehen (semantic versioning oder ein anderes System Ihrer Wahl kann verwendet werden).
Konfigurationsüberschreibung
Angesichts der Unterschiede und der Tatsache, dass Ihre Abhängigkeiten in Entwicklungs- und Produktionsszenarien unterschiedlich sein können, ist klar, dass wir verschiedene Konfigurationsdateien benötigen.

Docker Compose unterstützt das Zusammenführen verschiedener Compose-Dateien zur

Erzeugung der endgültigen Konfiguration. Wie das funktioniert, sehen wir am Beispiel:
In der Entwicklung und Produktion ist klar, dass wir unterschiedliche Konfigurationsdateien benötigen.

Docker Compose unterstützt die Zusammenführung verschiedener Compose-Dateien, um
die endgültige Konfiguration zu erhalten. Wie das funktioniert, zeigt folgendes Beispiel:

$ 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

Wie bereits erwähnt, unterstützt Docker Compose die Kombination mehrerer Compose-
Dateien, wodurch verschiedene Parameter im zweiten Datei überschrieben werden können. 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
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

Diese Syntax ist während der Entwicklung nicht sehr praktisch, wenn der Befehl
mehrmals ausgeführt werden muss.

Zum Glück sucht Docker Compose automatisch nach einer speziellen Datei mit dem Namen
docker-compose.override.yml um Werte zu überschreiben docker-compose.ymluseString
Wenn Sie die zweite Datei umbenennen, erhalten Sie dasselbe Ergebnis, jedoch mit dem ursprünglichen Befehl:

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

Nun, so merkt man sich es einfacher.

Interpolation von Variablen

Konfigurationsdateien unterstützen Interpolation
Variablen
und Standardwerte. Das bedeutet, 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 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 verwendet
in das Repository private.registry.mine.

Meine Prinzipien

Ansätze, die für mich hilfreich sind, könnten 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 benötigt werden, um all meine Umgebungen abzudecken, vermeiden größtmöglich
    Duplizierung.
  • Ich benötige einen einzigen einfachen Befehl für die Arbeit in jeder Umgebung.
  • Die grundlegende Konfiguration wird in der Datei docker-compose.yml.
  • Umgebungsvariablen werden verwendet, um Tags von Images oder andere
    Variablen zu definieren, die von Umgebung zu Umgebung variieren können (Staging, Integration,
    Produktion).
  • Die Werte der Variablen für die Produktion werden als Standardwerte verwendet, um
    Risiken zu minimieren, falls der Stack in der Produktion ohne festgelegte Umgebungsvariable gestartet wird.
    Um einen Service 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.
  • Lassen Sie uns ein einfaches Beispiel anschauen. docker-compose up -d.

Ich kann

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

docker-compose (docker-compose up) , um den Stack imEntwicklungsmodus mit dem Quellcode, der eingebunden ist, zu starten.
Entwicklungsmodus mit dem Quellcode, der in einem /project/src.

Ich kann dieselben Dateien in der Produktionsumgebung verwenden! Und ich könnte genau die gleiche Datei
für die Staging-Umgebung nutzen. Um dies in der docker-compose.yml Produktion zu implementieren, muss ich lediglich das Image mit einem vordefinierten Tag
im CI-Prozess erstellen und veröffentlichen:
export MY_SERVICE_VERSION=1.2.3 docker-compose -f docker-compose.yml build docker-compose -f docker-compose.yml push

In der Produktionsumgebung kann dies mit den folgenden Befehlen gestartet 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 durchführen möchten, müssen Sie einfach die

erforderlichen 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

Am Ende haben wir zwei verschiedene Docker-Compose-Dateien verwendet, die ohne

Konfigurationsduplizierung in jeder Ihrer Umgebungen verwendet werden können!
Duplikate von Konfigurationen können für jede Ihrer Umgebungen verwendet werden!

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

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster