Moby: Unterstützung für die Funktion "Erweitert" in Compose v3 / Docker-Stack-Bereitstellung hinzugefügt

Erstellt am 16. Feb. 2017  ·  165Kommentare  ·  Quelle: moby/moby

Wie in https://github.com/docker/compose/issues/4315 zu sehen ist, scheint die extends Funktion, die in docker-compose , trotz ihrer Fehler bei den Benutzern beliebt zu sein. Es wurde jedoch bisher nicht in die Implementierung des Compose-Formats der Engine aufgenommen. Bisher haben wir Benutzern empfohlen, bei der Verwendung von v3 einfach ihre Compose-Dateistruktur zu reduzieren, aber ist dies die langfristige Lösung, die wir bevorzugen? Wie können wir Benutzern, die sich auf diese Funktion verlassen, einen klaren Upgrade-Pfad bieten?

cc @dnephin @vdemeester

arestack kinfeature

Hilfreichster Kommentar

Nicht nur das, sondern das Changelog sagt "dies wurde entfernt, siehe 'Wie man ein Upgrade macht' für Details". Ich schaue mir "Wie man ein Upgrade macht" an, um Details zum Upgrade zu erhalten, und was darin steht, ist "siehe "Dienste erweitern" für Details". Ich gehe zu "Dienste erweitern" und denke, dass ich endlich eine Möglichkeit sehen werde, meine Dateien zu erweitern, nur um zu sehen, dass "dies entfernt wurde, siehe das Änderungsprotokoll für Details".

An dieser Stelle scheint dies ein grausamer Witz zu sein, den der Dokumentationsautor spielt.

Alle 165 Kommentare

Ich habe einige Notizen https://github.com/docker/compose/issues/4315#issuecomment -280617251 hinzugefügt, um die Erweiterungen, wie sie vorhanden sind, bis zur Docker Compose-Datei 2.1-Version zurückzubringen, ist keine gute Idee, aber die Hauptfunktion I miss ist in der Lage zu sein, abstrakte Dienste zu deklarieren (die niemals ausgeführt werden sollten, aber verwendet werden könnten, um allgemeine Eigenschaften von Diensten der Einfachheit halber zu gruppieren).

Ich stimmte den Kommentaren von docker/compose#4315 zu, dass die Art und Weise, wie extends funktionierte, etwas spartanisch war.

Ich werde keine Lösung empfehlen, aber FWIW, um das Ausmaß des Missbrauchs zu zeigen, hier sind die Konventionen, die den Anfang unserer Compose-Datei schmücken:

#
# Docker Compose configuration
#
# Due to lack of "expressivity" in Compose, we define our own couple of service
# "pseudo-types":
#
#   - image-only services (name: *-image)
#
#     The only goal of these is to build images. No other services build images.
#
#     These have entrypoint overridden to exit immediately.
#
#   - base services (name: *-base)
#
#     These contain common configuration and are intended to be extended.
#
#     Their command (not entrypoint, to keep the original one) is overridden to
#     exit immediately. Service must support a command to exit immediately.
#
#   - task services (name: *-task)
#
#     These are intended for running one-off commands.
#
#     Their default command is overridden to exit immediately. Service must
#     support a command to exit immediately.
#
#   - "real" services
#
#     These are actual services that stay up and running.
#
version: '2'
services:
  ...

Ich denke, dass die Erweiterungen wie in v2.1 eine gute Wahl sind. Extends ist eigentlich einfach und verständlich, dies ist zu gut für jede Umgebung, um eine kleine und lesbare Transformation zwischen dev, prod und env zu haben.

Eigentlich habe ich

  • eine gemeinsame docker-compose-Datei, die die Basisregeln darstellt
  • ein Entwickler-Docker, der es erweitert und mit Einrichtungen für Entwickler
  • ein Staging Docker komponieren, der auch gemeinsam und mit Einrichtungen für diese Umgebung erweitert wird
  • ein produktions-docker-komponieren, das sich auch allgemein erweitert und mit einrichtungen für diese umgebung, insbesondere containerreplikation, regeln für den neustart usw.

Das funktioniert, und ich verstehe nicht, warum wir in diesem Ticket eine komplette Neufassung suchen sollten, sondern eher die Beibehaltung eines interessanten Features. Extends ist ein guter Teil bei speziellen Anwendungsfällen, die andere Techniken nicht einfach lösen können. Ich bin zufrieden mit erweiterten Möglichkeiten.

Blockieren uns auch vom Upgrade auf das v3.x-Format.

Wir halten unsere Docker-Container-Definitionen in einem Ordner-pro-Instanz-Layout, wobei jeder Ordner ein docker-compose.yml , das die Umgebungsspezifikationen für die vorliegende Containerinstanz definiert. Um das allgemeine Zeug (DRY) auszuklammern, verwenden wir Basis-Service-Definitionen in einem übergeordneten Ordner und verwenden extend .

Wenn ich also eine bestimmte Containerinstanz verwalten muss, muss ich nur cd in den richtigen Ordner verschieben und kann dann ohne weitere Konfiguration direkt docker-compose-Befehle ausführen (keine -f Flags, die Teammitglieder benötigen nachschlagen oder wissen müssen, funktioniert einfach wie erwartet out-of-the-box).

Ich bin daran gehindert, Version 3 Compose-Dateien zu verwenden.

Ich verwende services.yml , um das Basislayout meiner Dienste zu definieren und erweitere es dann mit dev.services.yml für meine Entwicklungsumgebung (meistens Hinzufügen von Volumes), aber ich mag die (DRY) Wiederverwendbarkeit von Extends, wenn es war hinzugefügt. Es ist kein Dealbreaker, aber es würde mich davon abhalten, auf Version 3 umzusteigen, es sei denn, es gibt eine Funktion, die man unbedingt haben muss.

Ich bin jedoch nicht dagegen, die v2.1 'extends'-Lösung mit etwas Passenderem zu verbessern. Etwas wie abstrakte Dienste könnten sowohl sicherer als auch leistungsfähiger sein.

Zum Beispiel (da es abstrakt ist) könnte ich mir vorstellen, abstrakte Volumes/Mountpoints/Netzwerke zu unterstützen, bei denen der abstrakte Basisdienst einen lokalen Mountpunkt oder ein erforderliches Netzwerk für einen Dienst definiert, ohne den Hostteil zu definieren – was bedeutet, dass ein abgeleiteter Dienst dann definieren könnte/ Ordnen Sie den Host-Teil der Mounts/Volumes und Netzwerke zu, was in seiner Host-/Bühnenumgebung angemessen ist.

Das ist ein Beispiel für etwas, das wir mit 'extends' meines Wissens jetzt nicht machen können und würde einige interessante Möglichkeiten eröffnen.

Das Wegnehmen der erweiterten Funktion war überhaupt nicht hilfreich. Wir haben viele Webdienste mit den gleichen zugeordneten Volumes, Umgebungsvariablen und Labels gestartet. Sie haben auch dieselben Healthcheck-Richtlinien. Und ganz zu schweigen von Häfen. Das Kombinieren von Compose-Dateien mit mehreren Optionen -f ist mühsam und fehleranfällig, wenn Sie mit mehreren Projekten auf demselben Host arbeiten.

@shin- wird dies auf das 3.2-Schema zurückgebracht?

Ich würde wirklich sehr gerne extends wieder in das Dateiformat zurückbekommen. Ich habe es verwendet, um abstrakte Dienste für eine Reihe von Projekten weiter zu verfeinern. Ich verstehe, dass mehrere Optionen für -f fast die Rechnung erfüllen, aber es funktioniert nicht immer. Zum Beispiel ändere ich den Namen des abstrakten Dienstes ziemlich oft in einen im Kontext des jeweiligen Projekts aussagekräftigeren Namen. Dies ist etwas, das das Überschreiben, das mit mehreren -f Optionen auftritt, nicht unterstützt.

Es würde mir jedoch nichts ausmachen, die genauen extends verlieren, solange es eine andere Möglichkeit gibt, einen abstrakten Dienst in einer Datei zu "instanziieren".

Ich habe ein Setup mit einer gemeinsamen Service - Datei und Bündel von Dienstleistungen , die es, Ändern meist Band erstreckt, so dass ich sagen werde ich mich verlassen extends Feature und nicht sehen , andere gute Möglichkeit , meine Einstellung zu beschreiben.

--frustrated

+1
Ich kann die Logik hinter der Empfehlung sehen, Docker-Compose-Dateien zu reduzieren, aber ich mag die Idee nicht, den Code zu duplizieren, der unsere Entwicklungsdiensttopologie über mehrere Projekte hinweg definiert. Wir verwenden vorerst den Workaround -f mit Shell-Skripten, damit sich Entwickler nicht daran erinnern müssen, welche Dienste sie in welchen Fällen einschließen sollen.

Ich hoffe, dass hier eine zufriedenstellende Lösung gefunden wird, um eine bessere Faktorisierung von Compose-Strukturen zu ermöglichen!

Ganz oben auf meiner Anwendungsfallliste steht das DRYup meines konfigurationsverwalteten Horts von Diensten. Ich dachte, ich könnte 'erweitert' nutzen, wenn v3. Ich möchte nicht zu v2 zurückkehren ... und ich möchte keine Sonderfälle haben, in denen ich die Problemumgehung des -f-Prozesses verwenden muss.

Hey, hat jemand angefangen, daran zu arbeiten? Ich kann keine PR finden, um den Überblick zu behalten. Es würde uns auch hier einiges vereinfachen (Anwendungsfall sehr ähnlich wie oben beschrieben).

Da Version 3 eingefroren ist und ich eine Möglichkeit brauchte, eine gemeinsame Konfiguration zu teilen, habe ich einen kleinen Workaround gehackt, den ich hier teilen könnte (ich bin mir nicht sicher, ob dies der richtige Ort ist, aber zögern Sie nicht, mir zu sagen, wo ich sonst noch kann teile diese Info :))

Ich werde hier nicht darauf eingehen, da es eine Readme im Repo gibt.
Allen einen schönen ️

Bearbeiten:

Entschuldigung, hier ist der Link :D

+1

+1

+1

Danke für die +1
In der Zwischenzeit habe ich ein anderes docker noop image gefunden , das um den Faktor 10 ^ 3 kleiner ist (da der eigentliche noop in der Assemblierung geschrieben wird).

Leider ist in diesem Repo keine Lizenz enthalten. Ich habe dem Besitzer bereits auf Facebk eine Nachricht geschrieben, aber er hat noch nicht geantwortet. Vielleicht fügt er eine Lizenz hinzu, wenn mehr Leute ihn danach fragen :)

Etwas, das einigen der erweiterten Anwendungsfälle (in einer einzigen Datei) helfen könnte, wäre die Unterstützung für YAML-Anker: https://learnxinyminutes.com/docs/yaml/

Es scheint, dass die Validierung des JSON-Schemas für sie fehlschlägt service must be a mapping, not a NoneType. .

Hey, @grayside , Yaml-Anker funktionieren, zumindest für mich. Siehe meinen Kommentar oben, wie ich sie verwende.

Ok, aber es ist zu traurig, irgendeinen Noop-Service zu benutzen, nein?

Speziell für env-Variablen, welche Art von Werten verarbeiten diese env-Variablen? Wenn es um Geheimnisse geht, verwenden Sie die Funktion Schwarmgeheimnisse (oder eine andere Lösung für Geheimnisse). Wenn es um Einstellungen geht, ist es in Ordnung, dass die meisten Einstellungen App-/Dienst-spezifisch sind und nicht zwischen Diensten geteilt werden sollen.

Wenn Sie Einstellungen zwischen Diensten teilen müssen, ist dies meistens der Fall, wenn Sie dasselbe Container-Image starten, jedoch für unterschiedliche Laufzeitzwecke/Aufgaben (Verbraucher, Produzent, http-Worker, ...).

Wenn es um Einstellungen geht, ist es in Ordnung, dass die meisten Einstellungen App-/Dienst-spezifisch sind und nicht zwischen Diensten geteilt werden sollen.

Ich neige dazu, anderer Meinung zu sein. In dem Projekt, an dem ich gerade arbeite, verwende ich es zum Beispiel für Bände:

# Volume paths
environment:
  - &volume_a        volume-a:/usr/share/my_project/volumes/volume-a
  - &volume_b        volume-b:/usr/share/my_project/volumes/volume-b
  - &volume_c        volume-c:/usr/share/my_project/volumes/volume-c
  - &volume_d        volume-d:/usr/share/my_project/volumes/volume-d

Jetzt kann ich diese Volumes so angeben:

volumes:
  - volume-a:
  - volume-b:
  - volume-c:
  - volume-d:

services:
  some-service:
    image: some-image
    volumes:
      - *volume_a
      - *volume_b

  some-other-service:
    image: some-other-image
    volumes:
      - *volume_b
      - *volume_c

  some-third-service:
    image: yet-another-image
    volumes:
      - *volume_a
      - *volume_b
      - *volume_c
      - *volume_d

Dies macht es viel einfacher, durch verschiedene Volumes zu navigieren, ohne darüber nachdenken zu müssen, in welchem ​​Container Sie sich befinden. Imho, dies ist eine Möglichkeit, Ihr Docker-Compose-Setup konsistenter und einfacher zu verwenden und zu warten.

Ok ja, ich verstehe @JanNash, aber in Ihrem Beispiel unten haben Sie keinen Noop-Service, oder?

Aber Anker reichen für viele Fälle nicht aus.

Mein Fall beinhaltet die Unterstützung mehrerer Umgebungen für dasselbe Projekt. Hier können Sie ein Gerüst für unsere Projekte sehen .

Wenn Sie entwickeln, verwenden Sie devel.yaml , aber in der Produktion verwenden Sie prod.yaml . Es gibt auch test.yaml . Alle erben von common.yaml und erhalten einige allgemeine Variablen aus einer .env Datei.

Jeder hat seine Besonderheiten:

  • Die devel-Umgebung zielt auf Entwicklungsgeschwindigkeit ab, daher verwendet sie Build-Argumente, die schnellere Builds erzeugen, mountet Volumes mit dem App-Code vom Entwicklercomputer und fügt einige Dummy-Dienste hinzu, die die App von der Außenwelt isolieren.
  • prod zielt stattdessen auf Stabilität ab, lädt also den gesamten Code herunter und kompiliert ihn und bündelt ihn im Image selbst, anstatt Volumes zu verwenden. Builds sind langsamer, aber sicherer.
  • test zielt darauf ab, genau wie prod zu sein, jedoch isoliert von externen Diensten, um eine Verschmutzung der Außenwelt zu vermeiden.

Diese einfache Trennung ermöglicht eine sehr agile und flexible DevOps-Pipeline, in der jeder den gleichen Code in verschiedenen Phasen verwendet, mit nur kleinen Optimierungen je nach verwendeter Umgebung.

Ich habe versucht, das Dateiformat v3 zu erstellen, aber nicht nur extends wird nicht unterstützt, sondern auch .env , also wäre es im Moment ein Albtraum für die Wartung (mehr wegen des Fehlens von .env , um ehrlich zu sein). Bei der Entscheidung zwischen Swarm und DRY haben wir uns vorerst für DRY entschieden, aber irgendwann brauchen wir Swarm und ich hoffe, dass an diesem Tag beide Features wieder unterstützt werden... ☺️

... oder zumindest haben wir eine Möglichkeit, aus einer DRY-vollen Lösung ein gültiges DRY-less-Format zu generieren. Ich dachte, docker-compose bundle dafür, scheint aber im Moment zur Abwertung verdammt zu sein...

... oder wir haben ein anderes Tool, das alles macht (ich behalte auch ansible-container im Auge). Aber das ist sicherlich nicht "die Lösung".

Der Link in https://github.com/moby/moby/issues/31101#issuecomment -301212524 enthält eine README mit dem funktionierenden Beispiel von YAML-Ankern. Schau es dir an und versuche es heute noch einmal, es funktioniert gut. Ich bin mir nicht sicher, was ich anders mache.

@JanNash 👍

@Yajo Ich höre Sie und wie gesagt, es ist eine Problemumgehung und es wäre um eine Größenordnung besser, wenn es eine gute, integrierte DRY-Lösung von docker/moby/docker-compose gäbe (was auch immer die richtige Referenz ist) . Hoffen wir alle, dass das bald kommt, denn abgesehen davon bin ich mit Docker Compose ziemlich zufrieden

~Um der fehlenden .env-Unterstützung willen habe ich auch einen Workaround gehackt (mein Projekt ist noch nicht in Produktion, also ist mein Vortrag etwas billig, ich weiß :)). Um verschiedene Sets von Env-Variablen (z. B. Abhängigkeit und Image-Versionen/Tags) in verschiedenen Umgebungen (für mich derzeit lokale Entwicklung und ein kleiner Entwicklungsserver) zu unterstützen, verwende ich zwei Dateien, local.env und development.env und anstatt meine Befehle nur mit docker-compose <command> auszuführen, speichere ich entweder die entsprechende .env-Datei vorher in meine Shell oder führe sie so aus: (. local.env && docker-compose <command>) . Immer noch ein Hack, aber im Moment bin ich damit recht zufrieden.~

Lasst es euch gut gehen

Vielleicht sogar zwei Größenordnungen :D

@JanNash warte! wird .env in 3 nicht mehr unterstützt?

Ich weiß es eigentlich nicht, ich habe gerade in einem Kommentar gelesen, dass es nicht so ist.
Ich habe die Prozeduren local.env und development.env hauptsächlich verwendet, weil ich Autoenv nicht kannte, als ich es implementierte :D
Entschuldigung für mögliche Verwirrung.

Ah, @Yajo hat in diesem Kommentar die fehlende .env-Unterstützung erwähnt.
Könntest du das näher ausführen, @Yajo?

Oh Entschuldigung, meine Schuld. Es ist nicht so, dass es nicht funktioniert, es ist nur so, dass Sie es mit env_file: .env angeben müssen , anstatt wie zuvor automatisch erkannt zu werden. Kehren wir zum ursprünglichen Thema zurück.

Soll die Diskussion extends irgendwo fallen lassen? Ich würde es gerne durchlesen, bevor ich unseren Anwendungsfall vorstelle, weil ich denke, es ist gut verstanden, dass es sich um ein ziemlich gebrauchtes Feature handelt.

Hallo, ich habe eine Frage - wann? Wann wird die Unterstützung für "erweitert" in v3 wieder verfügbar sein?

@JanNash Sie können viel kleiner werden. Ich habe gerade ein Problem in Github gegen Ihr Repo eingereicht, ich habe auf meinem Computer von 750.000 auf 1200 Bytes heruntergefahren.

Ich sehe, dass ich im Moment im Schwarm nicht verlängern kann.
Irgendwelche Ideen, wie man den gleichen Dienst mit den gleichen Veröffentlichungsports und mit einem Container auf dem Dienst startet, der 1 zusätzliche Umgebungsvariable hat?

+1 für erweiterte Unterstützung beim Einsatz von Schwarmstapeln

Hi,
Wir führen eine Microservices-Anwendung aus, die in mehreren Git-Repositorys verteilt ist (jedes hat seine Docker-Compose-Datei).
Das Deployment wird von einer "root" docker-compose-Datei geleitet, die jeden Dienst erweitert: für uns wird diese extends Funktion wirklich für das Stack-Deployment benötigt.
Also auch +1, um die Unterstützung beim Einsatz von Schwarmstapeln zu erweitern
Vielen Dank.

Sie können die einfache YAML-Vererbung (siehe &default , <<: *default ) als vorübergehende Lösung verwenden:

version: '3'
services:
  worker: &default
    build: .
    command: bundle exec rake jobs:work
    env_file:
      - .env
    volumes:
      - .:/app
    depends_on:
      - db
      - redis
    links:
      - db:postgres
  web:
    <<: *default
    command: bundle exec puma -C config/puma.rb -p 3000
    ports:
      - "3000:3000"
  spring:
    <<: *default
    command: bundle exec spring server

Natürlich ist die Funktion extends besser

Wie wäre es, wenn Sie eine andere Datei erweitern?

Yaml hat keine Dateierweiterungsfunktion :(

Gibt es ein Update zu dieser Funktion von einem Mitwirkenden an Docker? Ist eine Wiedereinführung geplant? Falls nicht, gibt es ähnliche Pläne? Wenn nicht, warum nicht..?

@quolpr , ich fürchte, Ihr "YAML Simple Inheritance" -Code ersetzt extends in den meisten Fällen nicht, da der "Prototyp" (dh &default ) von Docker Compose immer als Dienst namens worker . Welcher Dienst a) also genau definiert werden muss, b) kann unerwünscht sein.

Auf jeden Fall ein interessantes Feature.

@laugimethods können Sie auch YAML-Referenzen verwenden:

version: '3'
services:
  spring:
    build: ./app
    command: /bin/sh -c "bundle exec spring server"
    volumes: &default_volumes
      - ./app:/app:delegated
      - bundle:/bundle:nocopy
  worker:
    build: ./app
    command: bundle exec sidekiq -v -C config/sidekiq.yml
    volumes: *default_volumes

(achten Sie auf &default_volumes und *default_volumes )

Aber ich kann wirklich nicht verstehen, warum die Funktion extends entfernt wurde 🤔

Zu Ihrer Information, um die fehlende Funktion "Erweitert" zu ersetzen, verwende ich jetzt eine Komposition/Zusammenführung von .yaml Dateien:
https://github.com/Logimethods/smart-meter/blob/master/README.md#docker -compose

Extends funktioniert, ist einfach und ausgereift, ich denke, wenn jemand Extend als Anti-Pattern sieht, dann benutze das einfach nicht, aber schneide es bitte nicht ab

Darf ich um eine klare Erklärung des beabsichtigten Ansatzes bitten, ohne extends ? Ich verwende es ausgiebig, insbesondere wenn ich von Dateien erbe, die in Git-Submodulen enthalten sind, um eine Definition eines Metaprojekts zu ermöglichen, das die anwendungsübergreifende Netzwerkverkabelung usw. behandelt. Obwohl ich mir bewusst bin, kann ich mehrere docker-compose.yml Dateien angeben und haben sie überschrieben, bedeutet dies, dass ich die Verbindungen in der Befehlszeile angeben muss, anstatt sie mit extends in die Quellcodeverwaltung einchecken zu können? Oder habe ich irgendwo in v3 ein neues Feature verpasst?

Ich verwende extends in mehreren Projekten stark, um einen gemeinsamen Satz von Dienstattributen für verschiedene Umgebungen und verschiedene Hosts zu erben (lies: Ich verwende extends , um von einer anderen Datei zu erben).

Nachdem ich die Entfernung des Schlüsselworts extends fassungslos gelesen und versucht habe, einen Ersatz zu finden, der keine Verkettung von -f docker compose files erfordert, bin ich sehr neugierig, was der Grund für die Entfernung von extends .

Ich verstehe das Problem mit links und volume-from aber es scheint das Beste zu sein, sie nur in Basis-Yml-Dateien zu verwenden.

Es wäre unwahrscheinlich, das Rad eines Autos zu entfernen, nur weil es sich daran gewöhnen könnte, das Auto auf den Kopf zu stellen... oder?

PS: Noop and Anchors sieht interessant aus, aber es fügt den einfachsten Projekten unnötige Komplexität hinzu ...

Als ganz, ganz einfaches Beispiel:

common/common.yml

services:
  web:
    image: alpine:3.6
    build: .
    environment:
      DOMAIN:
      PREFIX:

dev/docker-compose.yml

services:
  web:
    extends: ../common/common.yml
    service: web
  ports:
    - "8080:8080"

prod/docker-compose.yml

services:
  web:
    extends: ../common/common.yml
    service: web
  image: the-prod-image:latest-release
  ports:
    - "80:80"
    - "80:443"
  environment:
    NEW_RELIC_KEY:

Wie hält man DRY-Prinzipien ohne extends ?

Aus diesem Grund sehe ich derzeit keinen Grund für ein Upgrade von Version 2.1.

@teodorescuserban ,

Daisy Chaining -f Docker Compose files

Was ist daran ein Problem? Sie können Ihre eigenen Skripte mit kurzen Aliasnamen erstellen, um docker-compose aufzurufen.

Verwenden Sie folgende Struktur:

common/common.yml

services:
  web:
    image: alpine:3.6
    build: .
    environment:
      DOMAIN:
      PREFIX:

dev/docker-compose.yml

services:
  web:
    ports:
      - "8080:8080"

prod/docker-compose.yml

services:
  web:
    image: the-prod-image:latest-release
    ports:
      - "80:80"
      - "80:443"
    environment:
      NEW_RELIC_KEY:

Befehle

docker-compose -f common/common.yml -f dev/docker-compose.yml -p myproject up --build
docker-compose -f common/common.yml -f prod/docker-compose.yml -p myproject up --build

Ich kannte diese Funktion nicht. Obwohl es Ihre CLI zu einem macht, kann es funktionieren.

Ich denke, wenn das der offizielle Ersatz für extends , dann sollte es einen Weg geben, es einfacher zu machen.

Zum Beispiel:

docker-compose.yml

version: "3"  # or whatever
extend:
  - ./common/common.yml
  - ./dev/docker-compose.yml
services: # Not required now
  # etc.

Auf diese Weise können Sie auf eine einzelne docker-compose.yml Datei verweisen, die alles tut, was Sie brauchen.

Eine nützliche Alternative wäre die Unterstützung mehrerer Compose-Dateien in der COMPOSE_FILE Env-Variable.

@Yajo

Eine nützliche Alternative wäre die Unterstützung mehrerer Compose-Dateien in der COMPOSE_FILE-Env-Var.

Von https://docs.docker.com/compose/reference/envvars/#compose_file :

Diese Variable unterstützt mehrere Compose-Dateien, die durch ein Pfadtrennzeichen getrennt sind (unter Linux und macOS ist das Pfadtrennzeichen : , unter Windows ist es ; ). Beispiel: COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml . Das Pfadtrennzeichen kann auch mit COMPOSE_PATH_SEPARATOR angepasst werden.

@dermeister0 Sie können diese Dateien auch dauerhaft mit Tools wie https://github.com/ImmobilienScout24/yamlreader zusammenführen :

> yamlreader common/common.yml prod/docker-compose.yml > docker-compose-prod.yml
> docker-compose -f docker-compose-prod.yml -p myproject up --build

> cat docker-compose-prod.yml
services:
    web:
        build: .
        environment:
            DOMAIN: null
            NEW_RELIC_KEY: null
            PREFIX: null
        image: the-prod-image:latest-release
        ports:
        - 80:80
        - 80:443

@dermeister0 danke für deinen Vorschlag, leider ist es ein klobiger Ausweg. Wenn Sie extends , müssen Sie nicht wissen, wie genau Sie diese verketten müssen. Während ich damit leben kann, das für mich selbst zu tun, könnte ich diese Lösung niemals auf meine lieben Entwickler anwenden.

Mir war jedoch nicht bewusst, dass die env-Variable COMPOSE_FILE mehrere Werte enthalten kann. Danke @gsong ! Das ist großartig und kann es verwenden (ich definiere es in der Datei .env ). Es gibt hier ein einziges Problem: In den Basis- / Common-Dateien habe ich möglicherweise auch einige Dienste, die ich nicht benötige.

Nehmen Sie zum Beispiel eine flache gemeinsame Datei, die Datenbank- und Webcontainer definiert. Beim Staging möchten Sie, dass sie alle zusammengewürfelt werden, aber bei Prod möchten Sie separate Hosts für DB und Web.

Außerdem wird docker-compose.override.yml standardmäßig geladen.

https://docs.docker.com/compose/extends/#understanding -multiple-compose-files

Ich verwende diesen Ansatz mit Version 3.3:

  • füge allgemeine Konfigurationsoptionen und Dienste in docker-compose.yml ;
  • Verwenden Sie docker-compose.override.yml für spezifische Entwicklungskonfigurationen und Dienste (wie zum Beispiel xdebug);
  • Verwenden Sie docker-compose.staging.yml für spezifische Staging-Konfigurationsoptionen.

Hinweis: Ich führe Docker nicht in der Produktion aus.

Mit diesem Ansatz kann ich leicht lokal mit docker-compose build erstellen und wenn ich im Staging bereitstelle, verwende ich:

docker-compose -f docker-compose.staging.yml -f docker-compose.yml build

Ich verwende Apache und habe keine separaten virtuellen Hostdateien für Entwicklung und Staging. Ich habe ziemlich viel ausgegeben, um zu vermeiden, dass verschiedene Dateien vorhanden sind. Am Ende habe ich gesehen, dass der einzig gültige Ansatz darin besteht, <IfDefine> und Umgebungsvariablen (die ich im Umgebungsabschnitt der yml-Dateien festgelegt habe) zu verwenden, um beispielsweise die SSL-Konfiguration einzuschließen. Und ich verwende TLD und Domain-Präfix, damit ich etwas wie www.example.local http://www.example.local/ :8080 und www.staging.example.com http://www.staging.example.com haben kann / . Lokal laufen die Websites unter http und beim Staging auf https. Bei diesem Ansatz muss ich keine verschiedenen Versionen der Dateien pflegen. Ich denke, das gleiche könnte in der Produktion gemacht werden, aber wie gesagt, ich ziehe es vor, Docker in der Produktion zu vermeiden, atm.

Pfade sind alle relativ, sodass die Container in jeder Umgebung funktionieren.

Meine 2 Cent

-Filippo

In meinem Fall habe ich früher so etwas verwendet:

  • common.yml
  • devel.yml -> Common.yml erweitern
  • prod.yml -> Erweiterung von common.yml
  • docker-compose.yml -> local, git-ignored, symbolischer Link zur gewünschten Umgebung (devel oder prod).

Dank https://github.com/moby/moby/issues/31101#issuecomment -329482917 und https://github.com/moby/moby/issues/31101#issuecomment -329512231, von denen ich nichts wusste, Jetzt kann ich mit einem anderen Schema zu v3 wechseln:

  • docker-compose.yml -> was vorher common.yml war
  • devel.yml -> Docker-compose.yml überschreiben
  • prod.yml -> Docker-compose.yml überschreiben
  • docker-compose.override.yml -> local, git-ignored, symbolischer Link zur gewünschten Umgebung (devel oder prod).

Ich kann auch alle erforderlichen Hacks mit der env-Variablen ausführen, sodass das Problem in meinem Fall behoben ist. Vielen Dank! 🎉 (Entschuldigung, ich hätte die neuen Dokumente richtig lesen sollen, bevor ich mich beschwere).

PS: Trotzdem wäre es eine gute Sache, extends zurückzubekommen, aber zumindest haben wir eine faire Alternative. 😊

@shin- Zuerst war ich sehr enttäuscht, dass die extends Funktion in 3.0 fehlt, aber YAML-Anker (Beispiel: https://github.com/JanNash/docker-noop) wären a mehr als ausreichend Ersatz.

Das einzige ist, dass Sie, wie im obigen Beispiel, Ihre Anker in einen gültigen Abschnitt Ihrer docker-compose.yml Datei einfügen müssen.

Könnten wir eine (oberste) templates Eigenschaft oder versteckte Schlüssel wie in GitLab bekommen , um flexibler bei der Definition der Anker zu sein?

@schmunk42 schau mal auf https://github.com/docker/cli/pull/452

Das Problem bei der Verwendung von docker-compose.override.yml besteht darin, dass Sie nur einen Typ von Überschreibungen haben, den Sie einschließen müssen, und eine Ebene von Überschreibungen.

In meinem Fall möchte ich bestimmte Verhaltensweisen haben, die allen lokalen Entwicklungen gemeinsam sind, aber möglicherweise müssen sie sich geringfügig unterscheiden, wenn der Entwickler Windows, OSX oder Linux ausführt. Um dies in einem Docker-Compose v3-Kontext überschaubar zu halten, habe ich Linux-Benutzer, die mit dem gleichen Verhalten wie die Staging-Umgebung arbeiten, was funktioniert, aber bedeutet, dass sie mit anderen Entwicklern etwas nicht Schritt halten.

Ich vermeide es, -f für die lokale Entwicklung zu verwenden, weil ich festgestellt habe, dass es sehr anfällig für menschliche Fehler ist und es Probleme bereitet, sich bei zu vielen Dingen darauf zu verlassen. Die Auswahl einer Datei scheint vernünftig, die Auswahl mehrerer Dateien vermeide ich sorgfältig.

Zu Ihrer Information, ich denke, dass, sobald der oben erwähnte Hack mit x- und auch das Verketten von Docker-Compose-Dateien mit der Variablen COMPOSE_FILE in der .env Projektdatei das Docker- compose.override.yml sollte jeden Anwendungsfall lösen, auf den ich bisher gestoßen bin.

Die Yml-Anker sind auch eine nette Sache, die ich in naher Zukunft verwenden möchte.

Nicht sehr zufrieden mit der x- Hack-Schönheit, aber damit kann ich leben.

Danke Jungs für euren Input!

Es scheint, als würde das Entfernen von extends viel Sodbrennen verursachen und entweder den Wechsel zu v3 blockieren oder auf Hacks zurückgreifen. Ich mag die Möglichkeit, einen "Vorlagen"- (oder abstrakten) Dienst zu definieren, der einige allgemeine Dinge enthalten kann (z. B. Aktualisierungsrichtlinien).

Ich arbeite an einem einfachen Golang-Filter-Dienstprogramm, das eine Docker-Compose-Datei mit extends vorverarbeiten und eine saubere v3-Datei mit aufgelösten Erweiterungen ausspucken kann:
auflösen-zusammenstellen docker stack deploy -c docker-compose.yaml
(oder docker-compose up)

Wird dies zumindest für einige Ihrer Anwendungsfälle funktionieren / warum Gotchas?

@pnickolov Das wäre wunderschön für mich.

Ich habe nach Ansible-Container gesucht (ich benutze Ansible persönlich, aber noch nicht bei der Arbeit), was so aussieht, als würde es alles tun, was ich brauche, aber ein Skript wie Ihres wäre besser (weniger Abwanderung)

Solange es extends: Schlüssel rekursiv verarbeiten kann, würde ich mich freuen!

Ok, anscheinend haben wir Alternativen zu extends ...

Beunruhigend ist die Tatsache, dass das Projektmanagement von Moby die Aufrechterhaltung der Kompatibilität anscheinend nicht als Schlüsselelement betrachtet. Aufwärtskompatibilität ist für eine breitere Akzeptanz unerlässlich, insbesondere für große Anwendungen, die in der Produktion bereitgestellt werden. Wie könnten wir Docker Swarm / Docker EE vorantreiben, wenn es keine Garantie dafür gibt, dass Kernfunktionen wie extends bleiben? 👎
Ein guter Ruf ist schwer zu gewinnen und leicht zu verlieren...

Persönlich würde ich mich lieber auf native YAML-Funktionen verlassen, um die Aufgabe zu erfüllen, die von extends in v2 Syntax bearbeitet wird, anstatt ein benutzerdefiniertes Skript oder eine größere Lösung wie ansible. Ich hatte früher ähnliche Probleme und begann, meinen eigenen Konverter zu schreiben, bevor es Lösungen gab, wie die Verwendung mehrerer .yml-Dateien usw. (https://github.com/schmunk42/yii2-yaml-converter-command) - aber das war es nicht eine praktikable Lösung.

Für mich ist es auch in Ordnung, Funktionen abzulehnen, wenn dies zusammen mit einer Versionsrichtlinie erfolgt; Altes Zeug kann man nicht ewig tragen, auch wenn das Arbeit auf unserer Seite bedeutet.

@schmunk42 Das Verwerfen von Funktionen ist in Ordnung, aber nur, wenn:

  • das entfernte Feature wird nicht mehr wirklich genutzt oder ist ein echter Blocker für Evolutionen
  • es wird vorher angekündigt
  • ein Migrationspfad wird sofort bereitgestellt

Leider trifft keine dieser Anforderungen (in meinem Buch) auf die Einstellung von extends ...

@laugimethods Was ist der Grund, warum Sie v3 ?

@schmunk42 Wegen Schwarm:

Version 3.x, die neueste und empfohlene Version, die so konzipiert ist, dass sie zwischen Compose und dem Schwarmmodus der Docker Engine kompatibel ist. Dies wird mit einem version: '3' oder version: '3.1' usw. Eintrag am Stamm der YAML angegeben.

Der Befehl docker stack deploy unterstützt jede Compose-Datei der Version „3.0“ oder höher

Übrigens, mein Kommentar bezieht sich nicht nur auf extends , sondern auf jede (schmerzhafte) Einstellung, die in Zukunft auftreten könnte ...

Ja, wir haben das gleiche Problem wegen des Schwarmmodus.

Ich habe mich zuerst gefragt, warum zum Teufel die Docker-CLI jetzt in der Lage ist, --composer-file Eingaben zu verwenden. Aber nach unseren Erkenntnissen mit docker/swarm sieht es nach einer ziemlich komplizierten Sache aus, Stacks auf einem (selbstverwaltenden) Schwarm auszuführen, und es gibt mehrere gute Gründe, warum dies in die Engine verschoben wurde.

Um nur einige meiner Ergebnisse hier zu notieren ... der Übergang von v2 zu v3.4 ist alles andere als einfach.

Einige meiner Probleme:

  • es gibt andere nicht unterstützte Optionen wie volumes_from , die ziemlich leicht zu umgehen sind, da wir das sowieso entfernen wollten
  • .env Dateien (wie bei docker-compose ) haben keine Auswirkung auf Docker CLI
  • Das Angeben mehrerer Compose-Dateien ( docker stack deploy -c docker-compose.yml -c docker-compose.override.yml doro ) scheint nicht richtig zu funktionieren, es gibt keinen Fehler, aber es sieht so aus, als ob sie auch nicht richtig zusammengeführt werden - aber es gibt auch keinen Befehl wie docker-compose config , um dies zu überprüfen
  • es gibt keine "einfach zu installierende" (Pre-Release) Binärdatei für docker-compose die die v3.4 Syntax unterstützt; wie Docker Edge
  • externe Netzwerke müssen mit --scope swarm

CC: @handcode

Verwenden der neuesten Builds

  • docker 17.09.0-ce
  • docker-compose 1.17.0dev

Ich verwende jetzt diese Konfigurationspipeline, um meine Verwendung von _extend_ und _noop_ zu ersetzen.
Hält die Dinge ein bisschen trockener
Hoffe das hilft jemandem

base.yml (gemeinsame Definitionen, dies ist ein gültiges Yaml-Dokument, kann also mit _docker-compose config_ zusammengeführt werden)

version: '3.4'
networks:
  net_back:
    external: true

base-inject.yml (gemeinsame Ankerdefinitionen können leider nicht zu foo.yml eingefügt , kein idealer Weg, dies zu tun)

x-logging: &logging
  driver: json-file
  options:
    max-size: "50m"
    max-file: "2"

foo.yml (generische Stack-Definition, referenziert Objekte aus base.yml , Anker aus base-inject.yml und überschriebene Objekte in foo-dev.yml )

version: '3.4'
[[base-inject]]
services:
  foo:
    image: ${DOCKER_REGISTRY}/foo:${IMAGE_VERSION}
    volumes:
      - type: volume
        source: "volfoo"
        target: "/foo"
    networks:
     - net_back
    logging:
      <<: *logging

foo-dev.yml (pro Umgebungs-Stack-Definition)

version: '3.4'
services:
  foo:
    ports:
      - "8080:80"
volumes:
  volfoo:
    name: '{{index .Service.Labels "com.docker.stack.namespace"}}_volfoo_{{.Task.Slot}}'
    driver: local

Dann der Bereitstellungsbefehl:

docker stack rm stack_foo && echo "waiting..." && sleep 3 &&
  cat foo.yml | sed -e '/base-inject/ {' -e 'r base-inject.yml' -e 'd' -e '}' > ./foo-temp1.yml &&
  export $(sed '/^#/d' ./dev.env | xargs) &&
  docker-compose -f base.yml -f ./foo-temp1.yml -f foo-dev.yml config > ./foo-temp2.yml
  docker stack deploy --with-registry-auth --prune --compose-file ./foo-temp2.yml stack_foo
  1. Alten Stapel entfernen
  2. Warten Sie, bis sich der entfernbare Stapel ausbreitet
  3. Anker in generische Definition einfügen, in tmp-Datei speichern
  4. env-Dateivariablen aus Datei lesen + setzen
  5. Verwenden Sie docker-compose, um die drei Dateien zusammenzuführen
  6. Zusammengeführte Datei bereitstellen

Für diejenigen unter Ihnen, die nach extends in mehr als 3 Dateien komponieren möchten, habe ich gerade ein Tool namens baclin Hände gelegt. baclin linearisiert solche Direktiven und ersetzt rekursiv alle extends Direktiven durch ihren Inhalt. Dies ist Alpha-Software, der Code ist Teil meiner Maschinerie, da ich derzeit Code schreibe, um den Schwarmmodus und die Bereitstellung von Stacks zu unterstützen. Plattform-Binärdateien einer frühen Version von baclin sind hier verfügbar. Bitte melden Sie Kommentare oder Probleme hier .

Das ist wirklich verwirrend!
Wenn Sie das Dokument für die neueste Docker-Version ( v17.09 ) und auch das v17.06 lesen, sollte diese Funktion verfügbar sein.

$ head -n1 docker-compose.yml
version: '3'

Aber compose up ergibt

ERROR: The Compose file './docker-compose.yml' is invalid because:
Unsupported config option for services.admin_application: 'extends'

wenn Sie das Schlüsselwort extends .
Außerdem kann ich im compose Changelog nichts über das Entfernen von extends .

Was ist es nun?!
Wichtige Informationen wie diese sollten nicht schwer zu finden oder in einem obskuren Github-Problem versteckt sein.


$ docker --version
Docker version 17.09.0-ce, build afdb6d4

$ docker-compose --version
docker-compose version 1.16.1, build 6d1ac21

@jottr , Siehe Dokumente :

Das Schlüsselwort extended wird in früheren Compose-Dateiformaten bis zur Compose-Dateiversion 2.1 unterstützt (siehe erweitert in v1 und erweitert in v2), wird jedoch in Compose-Version 3.x nicht unterstützt.

Wenn Sie also extends möchten, müssen Sie bei version: '2.1' bleiben.

Mein Fehler. Es sollte sich immer noch oben im Dokument mit einem roten Warnzeichen für veraltete Versionen befinden.

Mein Fehler. Es sollte sich immer noch oben im Dokument mit einem roten Warnzeichen für veraltete Versionen befinden.

@jottr Verwenden https://github.com/docker/docker.github.io/issues/5340

In meinem Fall habe ich das docker-compose-override.yml wie folgt:
yaml version: "3.4" services: common: extra_hosts: - "host1:172.28.5.1" - "host2172.28.5.2" - "host3:172.28.5.3" networks: default: external: name: "common-network"
Und ich habe mehrere andere docker-compose.yml Dateien, die das Netzwerk und extra_hosts gemeinsam nutzen müssen. Wie kann man dies ohne die Erweiterungsfunktion tun?

yaml version: "3.4" services: mongo: image: "mongo" container_name: "mongo" hostname: "mongo" volumes: - "/opt/docker/mongo/default.conf:/usr/local/etc/mongo/mongod.conf" - /opt/data/mongo:/data/db" ports: - "27017:27017" command: "mongod --config /usr/local/etc/mongo/mongod.conf" networks: default: ipv4_address: "172.28.5.4"
Es wäre großartig, wenn docker-compose yaml-Anker und Referenzen zwischen verschiedenen Dateien unterstützt. Vielleicht, Anwenden von Ankern und Referenzen nach dem Zusammenführen von Dateien.
Zum Beispiel:
yaml version: "3.4" services: common: &common extra_hosts: ... networks: ...
yaml version: "3.4" services: mongo: <<: *common image: "mongo" container_name: "mongo" ...
Das Ergebnis sollte sein:
yaml version: "3.4" services: mongo: image: "mongo" container_name: "mongo" extra_hosts: // EXTRA HOSTS HERE networks: ...

@sandro-csimas dies ist möglich mit: https://docs.docker.com/compose/compose-file/#extension -fields
@shin- könnte dieses Ticket geschlossen werden?

@rdxmb Ich glaube nicht. Soweit ich sehen kann, können Sie nicht aus einer anderen docker-compose-Datei erweitern

Denke ich richtig, dass dies ein Problem für https://github.com/docker/compose/issues ist ?

Etwas Debugging:

# cat docker-compose.yml 
version: "3.4"
services:
  foo-not-bar:
    << : *common
  foo-bar:
    << : *common
    environment:
      - FOO=BAR 

x-common-definitions-for-all-our-services:
  &common
    image: phusion/baseimage
    environment:
      - FOO=NOTBARBYDEFAULT

Das funktioniert mit
docker stack deploy -c docker-compose.yml test

Bei Verwendung von docker-compose:

# docker-compose up 
ERROR: yaml.composer.ComposerError: found undefined alias 'common'
  in "./docker-compose.yml", line 4, column 10

Ändern der yml-Datei in:

version: "3.4"

x-common-definitions-for-all-our-services:
  &common
    image: phusion/baseimage
    environment:
      - FOO=NOTBARBYDEFAULT

services:
  foo-not-bar:
    << : *common
  foo-bar:
    << : *common
    environment:
      - FOO=BAR

funktioniert auch mit docker-compose.

Dachte also, dies sollte auch mit mehreren Dateien funktionieren, was nicht der Fall ist:

# docker-compose -f compose-services.yml -f compose-default.yml config > docker-compose.yml
ERROR: yaml.composer.ComposerError: found undefined alias 'common'
  in "./compose-services.yml", line 5, column 10
t# docker-compose -f compose-default.yml -f compose-services.yml config > docker-compose.yml
ERROR: yaml.composer.ComposerError: found undefined alias 'common'
  in "./compose-services.yml", line 5, column 10
# cat compose-services.yml 
version: "3.4"

services:
  foo-not-bar:
    << : *common
  foo-bar:
    << : *common
    environment:
      - FOO=BAR 

# cat compose-default.yml 
x-common-definitions-for-all-our-services:
  &common
    image: phusion/baseimage
    environment:
      - FOO=NOTBARBYDEFAULT

Das Zusammenführen ist jedoch natürlich mit einer einfachen Verwendung von cat :

# cat compose-default.yml compose-services.yml > docker-compose.yml && docker-compose up -d
WARNING: The Docker Engine you're using is running in swarm mode.

Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.

To deploy your application across the swarm, use `docker stack deploy`.

Creating network "test_default" with the default driver
Creating test_foo-bar_1 ... 
Creating test_foo-not-bar_1 ... 
Creating test_foo-bar_1
Creating test_foo-bar_1 ... done

Läuft auf xenial mit den Versionen:

# docker --version
Docker version 17.11.0-ce, build 1caf76c
# docker-compose --version
docker-compose version 1.17.0, build ac53b73

@rdxmb , danke!
Also sollte ich Compose-Dateien mit dem Befehl "cat" zusammenführen und die endgültige Datei ausführen.

Ich benutze auch die docker-compose config , um dies zu tun. Ein Beispiel für umgebungsspezifische Einstellungen:

Dies wird von der CI-Pipeline ausgeführt: docker-compose -f docker-compose.yml -f docker-compose.override.prod.yml config > docker-compose.prod.yml und dann verwende ich docker stack deploy -c .\docker-compose.prod.yml my-stack

Stimmen Sie dafür ab, die Erweiterungen sind sehr nützlich für v3.

Habe es viel mit v2 verwendet, wirklich sehr nützlich!
+1

Ich würde gerne extends Unterstützung in v3 sehen. Es würde mir sehr helfen, meine docker-compose.yml Datei zu TROCKNEN.

Es ist fast ein Jahr her, dass dieses Problem veröffentlicht wurde und es ist wirklich offensichtlich, dass eine Menge Leute diese Funktion brauchen. Ich habe jedoch weder gelesen, dass ein Docker-Entwickler auf diese Anfrage reagiert, noch eine Erklärung, warum sie vor der Veröffentlichung nicht in docker-compose v3 enthalten war.

Trauriger Zustand der Software, wenn wir unseren Kunden, die auf eine neue Technologie vertrauen, nicht einmal Funktionen kommunizieren oder warten können.

Eine mögliche Interpretation (und vielleicht auch eine Zusammenfassung des aktuellen Threads) der Situation sieht so aus:

  • YAML-Anker/-Referenzen plus Erweiterungsfelder von 3.4 erreichen fast dasselbe.
  • Multi-Datei kann zum Laufen gebracht werden. Siehe das einfache cat und den erweiterten Ansatz in diesem Thread. Der Kommentar zum einfachen Ansatz zeigt ein Problem mit Docker-Compose, das gegen Ende mehrere Dateien lädt (hat jemand dafür ein Problem erstellt?). Wenn das in docker-compose behoben wäre, müssten Sie die Datei überhaupt nicht zusammenführen. Für mich sollten Leute, die Unterstützung für mehrere Dateien wünschen, in docker/compose/issues wie von @rdxmb vorgeschlagen
  • Es wurde erwogen, extends (siehe GitHub-Projektereignisse , schöne Transparenz hier vom Docker-Team, danke!) schreibe immer noch eine Pull-Anfrage für extends denke ich.

Für mich eine absolut verständliche Sichtweise.

@aCandidMind Einverstanden.

IMHO, obwohl die von @aCandidMind erwähnten erhöhen sie die Komplexität des einfacheren und saubereren Mechanismus, der von extends bereitgestellt wird.
Vielleicht liegt es an mir, aber das Verschieben einer mäßig komplexen erweiterten Konfiguration auf Erweiterungsfelder wird viel schwieriger zu lesen und zu warten.
Nachdem ich viele Kommentare und Posts gelesen habe, ist mir immer noch nicht klar, warum Extends weggelassen wurde und was die Vorteile dieser Regression in den Fähigkeiten sind.

Es ist möglich, mit ein wenig Bash-Magie habe ich ein Test-Repo erstellt, damit Sie es selbst ausprobieren können.

Strukturieren Sie Ihren stack deploy Befehl einfach wie folgt:

docker stack deploy --compose-file=<(docker-compose -f docker/prod.yml -f docker/dev.yml config) <stackname>

@tylerbuchea - der einzige Nachteil dieser Bash-Magie ist, dass Sie möglicherweise ein WARNING: Some services (<service-name(s)>) use the '<key>' key, which will be ignored. Compose does not support '<key>' configuration . Dies kann einige Verwirrung stiften. Aber hey, es funktioniert 👍

@dnmgns du hast recht! Danke für den Hinweis. Wie @joaocc sagte, nichts wird die native Unterstützung übertreffen, aber die oben erwähnte Lösung ist die beste, die ich finden konnte, da es keine anderen Abhängigkeiten als bash gibt.

@tylerbuchea Ein schmutziger Weg ist, stderr einfach nach /dev/null umzuleiten :)
docker stack deploy --compose-file=<(docker-compose -f docker/prod.yml -f docker/dev.yml config 2> /dev/null) <stackname>

Ist keine Schande dabei 😄

Ich denke, die Dokumentation sollte diese Verwirrung um extend genauer beschreiben.
Die Beschreibung von extend leitet den Benutzer zu den Upgrade-Dokumenten weiter, und die Anleitungen für das Upgrade verweisen auf die Beschreibung von extend für weitere Informationen. Dies ist nicht hilfreich genug: Als Benutzer würde ich etwas Hilfe erwarten, wie man mit diesem ganzen Problem umgeht, welche Möglichkeiten ich habe und was ich beachten sollte. Ich bin mir sehr sicher, dass hinter der Entscheidung, extend aus v3 zu entfernen, eine klare Idee steckte.

Sehen:
https://docs.docker.com/compose/extends/#extending -services
https://docs.docker.com/compose/compose-file/compose-versioning/#upgrading

In Bezug auf @tylerbuchea großartige
Leider unterstützt es einige erweiterte Docker-Stack-Funktionen nicht:

WARNING: Some services (web) use the 'deploy' key, which will be ignored. Compose does not support 'deploy' configuration - use `docker stack deploy` to deploy to a swarm.
WARNING: Some services (web) use the 'configs' key, which will be ignored. Compose does not support 'configs' configuration - use `docker stack deploy` to deploy to a swarm.

Nicht, dass docker stack deploy seit dem Zusammenführen von https://github.com/docker/cli/pull/569 ab 18.03 das Zusammenführen mehrerer Compose-Dateien zu einer unterstützt. Es ersetzt den extends Schlüssel aus dem Composefile-Format v2 nicht vollständig, deckt aber hoffentlich viel mehr Anwendungsfälle ab 👼

Meine eigene Problemumgehung bestand darin, yq (kann bei Verwendung von Bash zu einem Einzeiler kombiniert werden):

yq merge --overwrite docker-stack.yml docker-stack.preprod.yml > merged-docker-stack.yml
docker stack deploy -c merged-docker-stack.yml preprod

@Lucas-C Sie warnen nur, dass die Ausgabe weiterhin Ihre Schlüssel deploy und config . Sie können dies überprüfen, wenn Sie docker-compose -f docker/prod.yml -f docker/dev.yml config ausführen

Es ist für Compose-Dateien v3.4 und höher. Es unterstützt Cross-Yaml-Referenzen (teilweise). Ich habe mit diesem zsh-Alias/perl-Skript fertig:

alias regen=$'perl -MFile::Slurp=read_file -MYAML=Load,Dump -MHash::Merge::Simple=merge -E \'
  local $YAML::QuoteNumericStrings = 1;
  $n=read_file("/data/docker-compose.yml");
  $s=Dump(merge(map{Load($n.read_file($_))}@ARGV));
  local $/ = undef;
  $s =~ s/\\bno\\b/"no"/g;
  say $s;
  \' $(find /data -mindepth 2 -maxdepth 4 -name docker-compose.yml) >! /data/x-docker-compose.yml'
regen
export COMPOSE_FILE=/data/x-docker-compose.yml
  1. /data/docker-compose.yml mit gemeinsamem Teil lesen.
  2. find all docker-compose rekursiv (zum Beispiel gibt es in diesem Projekt etwa 40 verschiedene Container/docker-compose.yml-Dateien)
  3. Stellen Sie jedem docker-compose.yml den Inhalt /data/docker-compose.yml voran
  4. verschmelzen
  5. Ergebnis in /data/x-docker-compose.yml speichern

Vorteile : Perl ist ein gemeinsames Werkzeug, alle Perl-Module auch, die Generierung ist schnell.
Nachteile : Ich hasse Hacks, aber es gibt keinen anderen Weg für DRY. Final docker-compose umfasst etwa 900 Zeilen. Wollen Sie wirklich, dass ich es von Anfang an als einzelne Datei unterstütze? Es ist eine Schande, binäres Docker mit Python umwickelt zu haben docker-compose umhüllt mit Perl-Hack.

Wie kann man einfach ein Feature wie Extends herausnehmen? Das scheint ein Kernfeature zu sein.

Die Verwendung von docker-compose config , die an die Standardeingabeoption von docker stack deploy -c - hat das Problem für mich gelöst:

docker-compose -f docker-compose.yml \
               -f docker-compose.extended.yml \
               config \
| docker stack deploy -c - my-stack

Ich habe dies nicht versucht, aber mir ist dies auch gerade in der Dokumentation zu docker stack deploy aufgefallen:

Wenn Ihre Konfiguration auf mehrere Compose-Dateien aufgeteilt ist, zB eine Basiskonfiguration und umgebungsspezifische Überschreibungen, können Sie mehrere --compose-file Flags bereitstellen.

Mit diesem als Beispiel:

docker stack deploy --compose-file docker-compose.yml -f docker-compose.prod.yml vossibility

https://docs.docker.com/engine/reference/commandline/stack_deploy/#compose -file

Ist die Begründung für das Entfernen von extends irgendwo dokumentiert? Es scheint nicht in den offiziellen Dokumenten erklärt zu werden, zB hier: https://docs.docker.com/compose/extends/#extending -services
Wenn die Benutzer die Gründe verstehen könnten, könnten die Benutzer eine bessere Vorstellung davon entwickeln, wie sie auf die Entfernung reagieren. Vielen Dank.

@shaun-blake Am Ende habe ich die mehreren Compose-Dateien verwendet. Das scheint der Ansatz zu sein, den die Leute verwenden. Statt Vererbung ist es eher ein Mix-In. Beim Erstellen oder Ausführen kopiere ich die richtige Umgebungs-Yaml-Vorlage in docker-compose.override.yml.

Mehrere Docker compose Dateien (zB: base.yml , local.yml , prod.yml ) nicht Service Gebrauch YAML Anker aus anderen Dateien lassen so faktorisierter Service - Definitionen nicht von mehreren yml Dateien definiert werden könnten .
Beachten Sie, dass diese Ausgabe auf Platz 13 der am häufigsten kommentierten : https://github.com/moby/moby/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-desc und auf Platz 3 mit den meisten Likes liegt .

Wenn die Benutzer die Gründe verstehen könnten, könnten die Benutzer eine bessere Vorstellung davon entwickeln, wie sie auf die Entfernung reagieren. Vielen Dank.

+1 zur Dokumentation zur Begründung für die Entfernung von extends ...

Immer noch kein _erweitert_ nach fast 1 und einem halben Jahr später. Komm schon, Entwickler, du entfernst etw nicht, ohne eine Alternative anzugeben.

Sie haben es getan, sie bieten eine Alternative namens Komposition an. Bitte lies meine Antwort im Thread.

-Filippo

Am 30. Juli 2018 um 09:41 Uhr schrieb Xiaohui Liu [email protected] :

Immer noch keine Verlängerung nach fast 1 ½ Jahr später. Komm schon, Entwickler, du entfernst etw nicht, ohne eine Alternative anzugeben.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an https://github.com/moby/moby/issues/31101#issuecomment-408790200 , oder schalten Sie den Thread stumm https://github.com/notifications/unsubscribe-auth/AAS_0AOynjpfVnVo4ZqciMbmjBmkcTQNcmJ5uLs4 .

@dedalozzo , "im Thread" == ?

Siehe meinen Kommentar hier:

https://github.com/moby/moby/issues/31101#issuecomment -329527600 https://github.com/moby/moby/issues/31101#issuecomment-329527600

Grundsätzlich müssen Sie eine Kette von .yml-Dateien verwenden, um die Konfiguration Ihrer Container zu überschreiben oder zu ändern.

Bitte lesen Sie "Mehrere Compose-Dateien angeben"

Sie können mehrere -f-Konfigurationsdateien bereitstellen. Wenn Sie mehrere Dateien bereitstellen, kombiniert Compose diese in einer einzigen Konfiguration. Compose erstellt die Konfiguration in der Reihenfolge, in der Sie die Dateien bereitstellen. Nachfolgende Dateien überschreiben und fügen ihre Vorgänger hinzu.

https://docs.docker.com/compose/reference/overview/ https://docs.docker.com/compose/reference/overview/

Dieser Ansatz verwendet Komposition über Vererbung, um mehr oder weniger das gleiche Ergebnis zu erzielen.

Am 30. Juli 2018 um 15:23 Uhr schrieb Serban Teodorescu [email protected] :

@dedalozzo https://github.com/dedalozzo , "im Thread" == ?


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an https://github.com/moby/moby/issues/31101#issuecomment-408880809 , oder schalten Sie den Thread stumm https://github.com/notifications/unsubscribe-auth/AAS_0FZO30NplqHRid_Id8VBOJW7nk5Iksp5uLxMDa

Könnten wir nicht die gleiche Erweiterbarkeit zurückbekommen, wenn wir kombinieren?
yaml-Erweiterungsfelder (komponieren 2.1+/3.4+)
mit den x- Feldern, auf andere Dateien zu

Wir könnten also einer Root-Liste mit include erlauben, die zu ladenden Dateien anzugeben.
sie würden in einem x-include abgelegt und wären sofort über Standard-YAML-Anker und -Zusammenführungen verwendbar.



Aktuelles komponieren v2.1+
# /docker-compose.yml
version: '2.1'

volumes:
  nginx_file_sockets:
    external: false
    driver: local

services:
  reverse_proxy:
    extends:
      file: reverse_proxy/docker-compose.yml
      service: proxy
    restart: 'always'
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  reverse_proxy_test:
    extends:
      file: reverse_proxy/docker-compose.yml
      service: proxy
    restart: 'always'
    ports:
      - "8080:80"
      - "8443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web:
    extends:
      file: webservice/docker-compose.yml
      service: app
    restart: 'always'
    environment:
      ENVIRONMENT: 'production'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web_staging:
    extends:
      file: webservice/docker-compose.yml
      service: app
    restart: 'no'
    environment:
      ENVIRONMENT: 'staging'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx

# /proxy/docker-compose.yml
version: '2.1'
services:
  proxy:
    build: ./
    volumes:
      - /certs:/certs:ro
# /webservice/docker-compose.yml
version: '2.1'
services:
  app:
    build:
      context: ./folder
      args:
        LINUX_VERSION: 20.s
        LINUX_FLAVOR: dash
    environment:
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - bootstrap.memory_lock=true
    ulimits:
      memlock:
        soft: -1
        hard: -1




Idee von Compose v3.X
# /proxy/docker-compose.yml
version: '3.9'
services:
  proxy:
    &proxy
    build: ./
    volumes:
      - /certs:/certs:ro
# /webservice/docker-compose.yml
version: '3.9'
services:
  app:
    &app
    build:
      context: ./folder
      args:
        LINUX_VERSION: 20.s
        LINUX_FLAVOR: dash
    environment:
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - bootstrap.memory_lock=true
    ulimits:
      memlock:
        soft: -1
        hard: -1
# /docker-compose.yml
version: '3.9'
include:
  - /proxy/docker-compose.yml
  - /webservice/docker-compose.yml

volumes:
  nginx_file_sockets:
    external: false
    driver: local

services:
  reverse_proxy:
    << : *proxy
    restart: 'always'
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  reverse_proxy_test:
    restart: 'always'
    << : *proxy
    ports:
      - "8080:80"
      - "8443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web:
    << : *app
    restart: 'always'
    environment:
      ENVIRONMENT: 'production'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web_staging:
    restart: 'no'
    extends:
      file: web1/docker-compose.yml
      service: app
    environment:
      ENVIRONMENT: 'staging'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx




Unterschied
@@ /proxy/docker-compose.yml @@
-version: '2.1'
+version: '3.9'
 services:
   proxy:
+    &proxy
     build: ./
     volumes:
       - /certs:/certs:ro
 ```

 ```diff
 @@ /webservice/docker-compose.yml @@
-version: '2.1'
+version: '3.9'
 services:
   app:
+    &app
     build:
       context: ./folder
       args:
         LINUX_VERSION: 20.s
         LINUX_FLAVOR: dash
     environment:
       - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
       - bootstrap.memory_lock=true
     ulimits:
       memlock:
         soft: -1
         hard: -1
 ```

 ```diff
 @@ /docker-compose.yml @@
-version: '2.1'
+version: '3.9'
+include:
+  - /proxy/docker-compose.yml
+  - /webservice/docker-compose.yml

 volumes:
   nginx_file_sockets:
     external: false
     driver: local

 services:
   reverse_proxy:
-    extends:
-      file: reverse_proxy/docker-compose.yml
-      service: proxy
+    << : *proxy
     restart: 'always'
     ports:
       - "80:80"
       - "443:443"
     volumes:
       - nginx_file_sockets:/sockets/nginx

   reverse_proxy_test:
-    extends:
-      file: reverse_proxy/docker-compose.yml
-      service: proxy
+    << : *proxy
     restart: 'no'
     ports:
       - "8080:80"
       - "8443:443"
     volumes:
       - nginx_file_sockets:/sockets/nginx

   web:
-    extends:
-      file: webservice/docker-compose.yml
-      service: app
+    << : *app
     restart: 'always'
     environment:
       ENVIRONMENT: 'production'
       DB_USER: ${WEB1_DB_USER}
       DB_PASSWORD: ${WEB1_DB_PASS}
     volumes:
       - nginx_file_sockets:/sockets/nginx

   web_staging:
-    extends:
-      file: webservice/docker-compose.yml
-      service: app
+    << : *app
     restart: 'no'
     environment:
       ENVIRONMENT: 'staging'
       DB_USER: ${WEB1_DB_USER}
       DB_PASSWORD: ${WEB1_DB_PASS}
     volumes:
       - nginx_file_sockets:/sockets/nginx
 ```
<hr>
Resulting in the final version, which should be already yaml parsable:

```yml
# /docker-compose.yml
version: '3.9'
#include:
#  - /proxy/docker-compose.yml
#  - /webservice/docker-compose.yml
x-include:
  /proxy/docker-compose.yml:
    version: '3.9'
    services:
      proxy:
        &proxy
        build: ./
        volumes:
          - /certs:/certs:ro
  /webservice/docker-compose.yml:
    version: '3.9'
    services:
      app:
        &app
        build:
          context: ./folder
          args:
            LINUX_VERSION: 20.s
            LINUX_FLAVOR: dash
        environment:
          - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
          - bootstrap.memory_lock=true
        ulimits:
          memlock:
            soft: -1
            hard: -1

volumes:
  nginx_file_sockets:
    external: false
    driver: local

services:
  reverse_proxy:
    << : *proxy
    restart: 'always'
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  reverse_proxy_test:
    << : *proxy
    restart: 'no'
    ports:
      - "8080:80"
      - "8443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web:
    << : *app
    restart: 'always'
    environment:
      ENVIRONMENT: 'production'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web_staging:
    << : *app
    restart: 'no'
    environment:
      ENVIRONMENT: 'staging'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx

AFAIK ist eine YAML-Funktion, die in die Sprachspezifikation selbst integriert ist, um zu vermeiden, dass sich Teile in derselben Datei wiederholen. Bei Verwendung unterschiedlicher Dateien ist das grundsätzlich nicht möglich.

Sie sollten diese Funktion der YAML-Spezifikation selbst vorschlagen.

Diese Diskussion brennt auf:

  • Warum ist docker-compose -f file.yml so viel besser als docker-compose -f file.yml -f file_extension.yml ?
  • Oder: Verdrahtung auf Kommandoebene _vs_ Verdrahtung auf Dateiebene.

Erst beim Arbeiten an der Kommandozeile werden die Unannehmlichkeiten deutlich. Das müssen wir für eine Sekunde anerkennen. Alles andere ist sowieso skriptfähig.

Wenn das das eigentliche Argument ist, dann hat docker-compose up service eine bessere Semantik als docker-compose -f service.yml up : Definiere alles, was für die lokale Entwicklung (auch bekannt als auf der Befehlszeile) benötigt wird, in docker-compose.override.yml .

Die gegebene Semantik ist sehr sauber und gut durchdacht. Die Übernahme von service.yml _für die Befehlszeilenverwendung_ bedeutet wahrscheinlich, die UX zu senken. Es gibt noch ein weiteres Argument: Während auf den ersten Blick klar ist, was ein docker-compose.yml ist, kann ein service.yml alles, wirklich alles sein.

Disclaimer: Eine provokative Meinung. :wink: Ich habe nicht alle möglichen Anwendungsfälle berücksichtigt...

Nach dieser längeren Diskussion nicht sicher, ob sie es jemals schaffen wird. IMHO, Extend war cool und muss zumindest vorsichtig missbilligt und dann diskutiert worden sein, anstatt es einfach wegzuwerfen.

Ich denke, wir könnten die Dokumentation über v2 vs. v3 verbessern. Viele gehen davon aus, dass v3 v2 ersetzt hat , aber das stimmt nicht ganz. Beide erhalten neue Funktionen, die sich auf ihre Anwendungsfälle konzentrieren. Dieses GH-Problem wurde ins Leben gerufen, damit wir die Diskussion darüber führen konnten, welche zukünftigen Funktionen benötigt werden, um von Docker-Compose in Swarm zu gelangen, und wie man die Dokumentation für die Verwendung von Docker-Compose, dem Compose-Dateiformat und Swarm-Stacks zusammen verbessern kann. Extends funktioniert auch in der aktuellen Version 2.4 immer noch hervorragend. Hoffentlich kann ich Ihnen helfen, Informationen zu den Lösungen anzubieten, die wir heute haben:

v2: Nur für Docker-Compose-Cli. Der Entwicklungsworkflow konzentrierte sich auf eine einzelne Maschine und einen einzigen Motor. Auch gut für CI-Build/Test-Workflows. Dieser Versionszweig hat erst im Dezember 2017 in v17.12 neue Funktionen erhalten

v3: Ideal für Swarm/Kube-Stacks, mit Multi-Node-Konzepten und unterstützt die meisten Docker-Compose-Cli-Funktionen.

Wenn Sie keine Kubernetes-Stacks von Swarm oder Docker Enterprise verwenden, gibt es keinen Grund, v3 zu verwenden . Bleiben Sie bei v2.4, und Sie erhalten alle Docker-Compose-Cli-Funktionen, einschließlich Extends, Depend_on, Extension Fields und sogar Depend_on mit Healthchecks (um Warte-Skripte zu vermeiden).

v3 wurde entwickelt, um zu versuchen, die Funktionen einer Docker-Compose-Cli-Welt mit einer einzigen Engine mit einer Multi-Node-Cluster-Welt zusammenzuführen. Nicht alle v2-Funktionen (wie Depend_on) sind in einem Cluster sinnvoll. Andere Funktionen (wie Extend) haben es einfach nicht in v3 geschafft, wahrscheinlich weil, bevor v3 existierte, der gesamte Code in docker-compose Python war, und damit v3.0 Swarm unterstützt, mussten sie das in docker cli Go neu schreiben. und jetzt schreiben sie es erneut in den Engine-Daemon, um schließlich eine Swarm-Stacks-API zu erstellen, die noch nicht existiert.

Für diejenigen, die dieses Problem noch nicht kennen, beachten Sie auch die vielen Arbeiten, die seit der Version 3.0 zur Lösung verschiedener Konfigurations-, Vorlagen- und Teamworkflow-Probleme durchgeführt wurden:

Die Dokumentation unter https://docs.docker.com/compose/extends/#extending -services sollte in Rot hervorheben, dass das Schlüsselwort extended in v3 entfernt wurde, da es wichtiger ist als nur ein _note_.
Ich migrierte und überflog die Dokumente, um herauszufinden, warum es nicht mehr funktionierte, verfolgte dann mehrere geschlossene Probleme, bevor ich hier landete, kehrte dann zu den Originaldokumenten zurück und bemerkte den Wortlaut.

Das Schlüsselwort extended wird in früheren Compose-Dateiformaten bis zur Compose-Dateiversion 2.1 unterstützt (siehe erweitert in v1 und erweitert in v2), wird jedoch in Compose-Version 3.x nicht unterstützt.

Könnte umformuliert werden als:

Das Schlüsselwort "extended" wurde in Compose Version 3.x entfernt, wird jedoch in früheren Compose-Dateiformaten bis zur Compose-Dateiversion 2.1 weiterhin unterstützt (siehe "extended in v1" und "extended in v2".

Es ist ein kleiner Unterschied, der aber beim Überfliegen von Dokumenten leicht zu übersehen ist.

@krisrp PR gestartet ^^^

Danke @BretFisher

Gibt es Pläne, v2 in "version: docker-cli" und v3 in "version: swarm/kube" umzubenennen?
Es wäre sinnvoller, sie so zu differenzieren, wenn man bedenkt, wie v3 v2 in den meisten anderen Versionsschemata ersetzt. Gegenwärtig werden beide gepflegt und divergieren, also wenn ich mich nicht irre, scheint es, als würden sie beide noch eine Weile da sein.

@krisrp Im Gegenteil, der Grund für das Inkrementieren einer Hauptversionsnummer besteht darin, die Divergenz in der Kompatibilität zu signalisieren.

@ cpuguy83 Ich habe nichts anderes impliziert. Entschuldigung, dass ich nicht klarer oder expliziter bin.
IIRC Gnome 2 & 3 hatten diese Verwirrung auch vor Jahren, als unabhängige Forks von jedem gepflegt wurden.

Ich möchte diesen Thread nicht entgleisen, um die Semantik der Versionierung (schlechtes Wortspiel) zu diskutieren, also belasse ich es dabei. @BretFishers Beitrag letzte Woche über die Verbesserung der Dokumentation zu v2 vs. v3 hätte mir und wahrscheinlich anderen geholfen.

@shin- @cpuguy83 Wenn man sich dieses Problem über ein Jahr später ansieht, was _ist_ der Grund dafür, es nicht wieder in Version 3 hinzuzufügen?

Ich konnte nicht viel darüber finden, außer "wir könnten es anders machen" (aber keine wirklich bessere Lösung angeboten)
Gibt es eine technische Einschränkung? Oder fehlt nur ein Pull-Request?

Immerhin laufen meine Compose 2.1-Dateien immer noch einwandfrei.

Nicht nur das, sondern das Changelog sagt "dies wurde entfernt, siehe 'Wie man ein Upgrade macht' für Details". Ich schaue mir "Wie man ein Upgrade macht" an, um Details zum Upgrade zu erhalten, und was darin steht, ist "siehe "Dienste erweitern" für Details". Ich gehe zu "Dienste erweitern" und denke, dass ich endlich eine Möglichkeit sehen werde, meine Dateien zu erweitern, nur um zu sehen, dass "dies entfernt wurde, siehe das Änderungsprotokoll für Details".

An dieser Stelle scheint dies ein grausamer Witz zu sein, den der Dokumentationsautor spielt.

Letztlich wird das Format „Stack“ hier nicht gesteuert und ist Teil der Docker-CLI.

Ich persönlich weiß nicht, warum es von v3 ausgeschlossen wurde ... Ich glaube auch nicht, dass jemand versucht hat, es hinzuzufügen.
Es könnte am besten sein, dies in Docker/cli zu erwähnen ... vielleicht sogar nur eine PR mit einer hochrangigen Doc-Änderung, die so wirkt, als ob die Funktion vorhanden wäre, damit sie diskutiert und die Implementierung hinzugefügt werden kann, sobald das Design genehmigt ist .

Grundsätzlich, wenn jemand es will, machen Sie eine PR. Ich schlage die Änderung des Dokuments vor, nur um sicherzustellen, dass Sie nicht viel Zeit verschwenden, falls sie abgelehnt wird ... da ich mir wieder nicht sicher bin, warum sie in v3 weggelassen wurde.

Das gleiche wie oben. Warten Sie, bis dies behoben ist, bevor Sie docker-compose erneut verwenden.

+1 Bitte beheben Sie das Problem, wir haben erweiterungsbasierte Compose-Dateien und können das Compose daher nicht für den Schwarm verwenden.

+1 für Erweiterungsfunktion

Gibt es darüber irgendwelche Neuigkeiten?

Warte immer noch darauf

Hier gilt das gleiche. Warte noch.

Irgendein Update?

Gab es jemals einen Grund, warum es herausgenommen wurde?

Am Mo, 5. August 2019, 11:10 Uhr schrieb Jaykishan, [email protected] :

Irgendein Update?


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/31101?email_source=notifications&email_token=ABOE6GA4CXY6ESMZMTDSFGDQC74CZA5CNFSM4DANZGS2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVDZLOKTORDN5WWZ
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/ABOE6GCEFFJ3SOLDWRWX2IDQC74CZANCNFSM4DANZGSQ
.

Irgendein Update?

also... es sind fast 3 jahre...
Aber ich habe immer noch Hoffnung, dass es landet :D

Es muss eine Alternative zu Erweiterungen geben, wenn sie nicht zurückkommt. Warum nicht abstrakte Dienste zulassen? Das Dateiformat wäre flach und alle Leistungserklärungen würden in einer Datei vorliegen. Sie könnten abstrakte Dienste in Verbindung mit der Fähigkeit von yaml verwenden, Aliase für einen Knoten hinzuzufügen (über ein & ), diese Aliase über den Operator <<: wiederzuverwenden.

Warum 3 Jahre!! es scheint, dass du arbeitest und dich auf Dinge konzentrierst, die niemanden interessiert

Gibt es hierzu Neuigkeiten?

Das ist erbärmlich. Terraform verwendet Komposition - also ist es machbar, warum kann Compose nicht dieser guten Designpraxis folgen?!
Zusammensetzung der Terraform-Module
Best Practices für Terraform

"erbärmlich", nett.

@Cristian-Malinescu Mach weiter, implementiere es bitte.
Dies ist kostenlose und Open-Source-Software.

Anstatt sich wie jeder andere in diesem Chat zu beschweren.
Das bringt hier wirklich keinen Mehrwert.
Wie schon mehrfach gesagt, wollte das bisher niemand umsetzen,
Es ist also nur ein Problem, das jemand anderes beheben sollte, danke.

@luckydonald Danke @Cristian-Malinescu mit einer einfachen / passiv-aggressiven Antwort wegzuschieben, es ist, als ob es immer nicht hilft. @Cristian-Malinescu Es ist machbar, da es bereits zuvor getan wurde, aber entfernt, es muss (hoffe ich) einen Grund geben Gegenstand?

Der Thread wurde überflogen und die Nutzung unterstützter YAML-Funktionen wurde erwähnt.

Dachte, dieses Beispiel könnte helfen.

@nomasprime danke für diesen Fund! Ich habe mich für mein Projekt zwischen v2 und v3 entschieden, und dies löste das große Dilemma in diesem Thread. Überrascht, dass diese alternativen Lösungen in den offiziellen Dokumenten für die

Schön, klingt nach einer guten Gelegenheit, den Link Request docs changes in der rechten Navigationsleiste der Dokumentseite zu verwenden.

@nomasprime Ja , diese Idee gab es in diesem Thread schon einmal.

Wenn dies mit einem Dateilademechanismus für andere yml-Dateien kombiniert werden könnte, ist das alles, was wirklich benötigt wird, um die gesamte alte depends Funktionalität zu haben.

Siehe oben, zB https://github.com/moby/moby/issues/31101#issuecomment -413323610

Es wäre nicht sehr _lesbar_, aber es wäre zumindest _möglich_.

@nomasprime danke für diesen Fund! Ich habe mich für mein Projekt zwischen v2 und v3 entschieden, und dies löste das große Dilemma in diesem Thread.

@arseniybanayev Der Artikel auf Medium sagt nur über v3, aber neuere Versionen von v2 unterstützen auch Anker und Erweiterungsfelder . In meinem Fall wähle ich v2 (genauer 2.4), weil ich docker-compose und nicht swarm (und v3 unterstützt einige Funktionen von v2 wie die Begrenzung des Containerspeichers nicht ).

und v3 unterstützt einige Funktionen von v2 nicht, wie die Begrenzung des Containerspeichers

v3 unterstützt die Speicherbegrenzung, aber das Feld befindet sich unter deploy -> resources -> limits https://docs.docker.com/compose/compose-file/#resources

@thaJeztah Ich meine, für docker-compose (weil ich in dem Projekt, auf das ich mich in meinem vorherigen Kommentar bezog, keinen Schwarm verwende). IIRC-Bereitstellung ist nur für Schwarm, nicht wahr?

Wäre es sinnvoll, eine separate Konfiguration für Swarm und Local zu erstellen? Scheint, als ob diese beiden miteinander in Konflikt geraten. Verständlicherweise möchte Docker die Schwarmnutzung erhöhen, aber viele Leute verwenden Compose nur für die lokale Entwicklung.

Ich für meinen Teil habe noch nie Swarm-and-Run-Container in der Produktion mit ECS, k8s oder GAE verwendet.

Die meisten Optionen sollten sowohl für Swarm-/Kubernetes-Dienste als auch für Container, die über Compose bereitgestellt werden, übersetzbar / verwendbar sein. Ich müsste prüfen, warum memory Limits für docker-compose

Ich vermisse immer noch die Erweiterungsfunktion, aber für meinen Hauptanwendungsfall habe ich über die COMPOSE_FILE Umgebung zu mehreren Docker-Compose-Dateien gewechselt. Ich verwende es hauptsächlich, um die gleiche Basis docker-compose.yml für dev und prod mit unterschiedlichen Passwörtern oder Konfigurationen zu verwenden.

Beispiel:

  • auf dev: export COMPOSE_FILE= docker-compose.yml` # default
  • auf prod: export COMPOSE_FILE= docker-compose. yml:docker-compose.prod.yml ` # verwendet beide yaml-Dateien

In docker-compose.prod.yml überschreibe ich einfach die env vars mit den prod-Passwörtern.

Dieses Setup ist einfach und ich muss nicht immer mehrere "-f" zum Befehl docker-compose hinzufügen. Ich muss nur die env var COMPOSE_FILE auf dem Entwicklungscomputer und dem Server unterschiedlich setzen und die Datei docker-compose.prod.yml ignorieren.

Warte noch :)

Ich habe dies als eine Möglichkeit verwendet, um zu erweitern:

docker-compose \
  -f ./docker/base.yml \
  -f ./docker/extended.yml \
  up

Aber in der Datei zu erweitern wäre schöner, kein zusätzliches Bash-Skript erforderlich.

Ich habe dies auch verwendet, um das Bash-Skript dynamisch zu erweitern:

extended_docker_compose="
  version: '3.5'
  services:
    my-service:
      restart: always
"

echo "$extended_docker_compose" | docker-compose \
  -f ./docker/base.yml \
  -f /dev/stdin \
  up

@dave-dm das sind schlichte alte Überschreibungen!

Ich glaube, dies ist ein potenziell gültiger Anwendungsfall für Extends

https://github.com/NerdsvilleCEO/devtools/blob/master/doctl/docker-compose.yml#L10

Ich habe einen docker-compose Wrapper, den ich für eine Umgebung von Diensten verwende https://github.com/nowakowskir/docker-compose-wrapper

BEARBEITEN: Ein weiterer möglicher Anwendungsfall ist, dass jemand einen LAMP/LEMP-Stack hat und diese Dienste für die Verwendung mit einem bestimmten Dienst wie WordPress erweitern möchte

Warte immer noch seit 2017, während ich nach Alternativen zum Verfassen von Docker suche.

@nomasprime Ja , diese Idee gab es in diesem Thread schon einmal.

Wenn dies mit einem Dateilademechanismus für andere yml-Dateien kombiniert werden könnte, ist das alles, was wirklich benötigt wird, um die gesamte alte depends Funktionalität zu haben.

Siehe oben, zB #31101 (Kommentar)

Es wäre nicht sehr _lesbar_, aber es wäre zumindest _möglich_.

@luckydonald danke für den Hinweis. Seltsamerweise gibt es keine integrierte YAML-Funktionalität , die sicherlich viele Probleme lösen würde.

Es sieht so aus, als ob es ziemlich einfach wäre, eine Drittanbieterlösung zu implementieren, also bin ich mir nicht sicher, warum dies nicht auf v3 übertragen wurde 🤷‍♂

Eine kleine Erinnerung, dass viele Leute diese Funktion mögen würden :)

Was ist der Grund, es nicht auf v3 zu portieren?

Ich habe es vergessen, aber gibt es einen tatsächlichen Grund, warum es weggenommen wurde?

Am Mi, 6. Mai 2020, 23:14 schrieb Julien Marechal, [email protected] :

Eine kleine Erinnerung, dass viele Leute diese Funktion mögen würden :)


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/31101#issuecomment-624919070 , oder
Abmelden
https://github.com/notifications/unsubscribe-auth/ABOE6GGDIVGATP734YJA4UTRQHOLJANCNFSM4DANZGSQ
.

Die Art und Weise, wie Yaml-Anker diesen Anwendungsfall handhaben, ist im Vergleich zu extend etwas umständlich. Meines Erachtens stammt seine Kraft hauptsächlich aus der rekursiven Verschmelzung von Elementen. Anker bringen Sie vielleicht zu 75 % dorthin – sie führen yaml nicht rekursiv zusammen; Ihr gesamtes Zusammenführen geschieht auf der obersten Ebene. Wenn Sie auf eine Vorlage für einen verankerten Dienst verweisen und dann den Block environment , wird der Umgebungsblock des verankerten Dienstes überschrieben, anstatt zusammengeführt. Sie müssen jedes Wörterbuch in einem rekursiven Verzeichnisbaum verankern und referenzieren, um dem Verhalten des Schlüsselworts extend .

Ein Beispiel:

# anchors for the service, environment, deploy, and deploy.placement blocks
# you'll need an anchor for every dict that you want to merge into
x-common-app: &common-app
  image: app:1.0
  environment: &common-app-environment
    common_option: a
    overwrite_option: b
  deploy: &common-app-deploy
    max-replicas-per-host: 3
    placement: &common-app-deploy-placement
      constraints:
        - 'node.labels.app_host==true'

services:
  myapp: << *common-app
    environment: << *common-app-environment
      foo: bar
      baz: xyzzy
      overwrite_option: quz
    deploy: << *common-app-deploy
      replicas: 15
      placement: << *common-app-deploy-placement
        preferences:
          - spread: node.labels.region

# The above yields the following:
services:
  myapp:
    image: app:1.0
    environment:
      common_option: a
      overwrite_option: quz
      foo: bar
      baz: xyzzy
    deploy:
      replicas: 15
      max-replicas-per-host: 3
      placement:
        constraints:
          - 'node.labels.app_host==true'
        preferences:
          - spread: node.labels.region

In diesem Beispiel sieht es vielleicht nicht so nervig aus, aber es wird nervig und weniger lesbar, wenn Sie mehrere (10+) Dienste aus einem Erweiterungsblock erstellen.

Meiner Meinung nach ist ein ideales Szenario eine Kombination aus dem YAML-Anker-Ansatz und dem extend -Ansatz – Erlauben Sie extend nur von einem x- Erweiterungsfeldblock der obersten Ebene

In meiner Organisation fanden wir Yaml-Anker ein bisschen syntaktisch schlampig, also haben wir die extend Funktion im Grunde in einem externen Python-Skript neu implementiert. Das funktioniert für uns, aber es ist eine lahme Art, mit etwas umgehen zu müssen. Ebenso mussten wir unsere eigenen externen Tools erstellen, um die Entfernung von depends_on für v3/Swarm-Stacks zu bewältigen.

Ich habe in letzter Zeit viel gitlab CI YAML gemacht. Es hat genau diese Funktionen, die sooo schön sind, um lesbare und überschaubare Vorlagen und endgültige Konfigurationen zu erreichen:

  • Sie können andere YAML-Dateien einschließen (gut für Vorlagen)
  • Sie können erweitern (auch projektübergreifend/mit Remote-Ressourcen über https). Die Extend-Dokumentation beschreibt genau das, was @a-abella für das Compose-Format beschreibt.
  • Sie können sich auch "verstecken", damit Sie nicht als das echte Zeug angesehen werden. Im Compose-Format ist es x- , in gitlab CI ist es stattdessen ein anfängliches . .

Dies ist genau der Funktionssatz, der diese Dateien erträglich macht.

Ich bin aus den Docker-Dokumenten zu diesem Problem gekommen, in meinem Fall wollte ich mein docker-compose Setup als Vorlage erstellen, und als "Abhilfe" befolgte ich die obigen Ratschläge und entschied mich, nach einem vorhandenen Vorlagenprogramm zu suchen. Ich werde diese Stunden nicht zurückbekommen, also beschreibe ich ein wenig von dem, was ich hier gefunden habe, unabhängig von jeglicher Diskussion über diese tatsächliche Funktionsanfrage, jedoch kann es sein, dass die Beteiligten die Verwendung eines YAML-basierten Vorlagensystems für eine Compose-Datei zu generieren, anstatt diese Funktion in docker-compose selbst zu integrieren, könnte in Bezug auf die Kapselung und die Auswahl des richtigen Tools für den Job besser geeignet sein.

Für einen bestimmten Kontext verwende ich einen einfachen Reverse-Proxy mit Let's Encrypt und mehreren Anwendungscontainern (Nextcloud für jetzt, einen für mich und einige separate für Freunde) - in diesem Fall wollte ich eine Vorlage der Nextcloud-Container so erstellen dass ich Fehler und Duplizierung mit Tastenanschlägen für sehr ähnliche Setups vermeide. Folgende Pakete habe ich probiert:

ytt scheint sehr umfassend zu sein und ist die einzige Möglichkeit, YAML nativ zu verwenden. Es schien leistungsstark und das richtige Werkzeug für den Job zu sein, und es verwendet Starlark, eine Obermenge von Python, direkt in der YAML-Datei, um die Verarbeitung durchzuführen. Nach kurzer Zeit wurde die Vorlage jedoch sehr unordentlich, und das Vermüllen von Codefragmenten und YAML-Fragmenten sowie das Mischen von Python-Datentypen wie Wörterbüchern und Arrays und YAML-Fragmenten (die irgendwie wie Text verarbeitet zu werden scheinen, ein bisschen wie beim Verwenden eine HTML-Template-Engine, die Tags wie Strings ausgibt) führte schließlich zu zu vielen Fehlern und einer zu unordentlichen Datei. Dhall scheint auch sehr umfassend zu sein und verwendet eine einzigartige Muttersprache, die in eine Vielzahl von Formaten ausgegeben werden kann; Es scheint eher eine Metaprogrammiersprache als ein Template-System zu sein, aber da die Syntax funktional und ziemlich streng typisiert ist, wurde es schnell komplexer, als es sich für ein einfaches Template für unstrukturiertes YAML gelohnt hätte. Da es ein bisschen wie eine Mischung aus JSON und Haskell aussieht, war zu viel Nachdenken erforderlich, um das, was ich brauchte, in die Sprache zu integrieren.

Interessanterweise verwendete etwas, das sowohl bei Dhall als auch bei ytt schwierig war, parametrisierte Feldnamen, beide hätten ansonsten gut genug funktioniert, aber ich muss den Namen meiner Instanz in den Dienstnamen und Volume-Namen erscheinen lassen, und in beiden erreichte das war etwas hässlich; Argumente für die Werte in einem Hash zu verwenden ist einfach, aber die Verwendung dieser Argumente in den Namen der Schlüssel war chaotisch oder ich konnte nicht finden, wie man es sauber macht, außerdem erzwingt Dhall die Typsicherheit und dies widerspricht einfach diesem Konzept. Bei Jsonnet war es einfach, den Ausdruck in eckige Klammern zu setzen.

CUE und Jsonnet sind beide JSON-orientiert, aber es ist überhaupt nicht schwer, diese über einen Konverter zu führen, und es scheint wieder so zu sein, dass CUE wie Dhall viele leistungsstarke Funktionen hat und aus Mängeln in Jsonnet geboren wurde, jedoch nur teilweise in der Dokumentation , es stellte sich heraus, dass es bereits übertrieben war; Vielleicht mit viel mehr Zeit, um es richtig zu lernen, wäre es die bessere Option, aber es scheint, dass CUE mehr auf Validierung und Schemata als auf einen einfachen Vorlagenjob ausgerichtet ist, und so wechselte ich schnell zu Jsonnet und beendete den Job ziemlich schnell.

Erst nachdem ich all dies abgeschlossen hatte, wurde mir während der ganzen Zeit, in der ich diese Tools mit der Einfachheit von Liquid-Tags oder ähnlichen HTML-Templates vergleicht, klar, dass ich Liquid eigentlich wahrscheinlich einfach hätte verwenden können. Ich habe es nur im Kontext einer Jekyll-Site verwendet, daher ist es nie aufgetreten, um ein eigenständiges Paket zu erhalten, jedoch mit grundlegenden Schleifen und Listen und der Möglichkeit, Ausdrücke direkt in In-Place-Text auszuwerten, hätte dies wahrscheinlich war auch viel besser für den Job; Jsonify ist für JSON wahrscheinlich überlegen, aber Liquid könnte in reinem YAML arbeiten und so wird die Datei wieder besser lesbar.

+1 docker-compose war eine Inspiration für die maßgeschneiderte Lösung, die ich bei der Arbeit implementiert habe, seit dieses Ticket erstellt wurde, um die Migration einer großen Anzahl von Testumgebungen auf k8s zu unterstützen. Ich war sehr vorsichtig, um Schnickschnack zu vermeiden, rechtfertigte aber ziemlich schnell ein analoges Merkmal. Die philosophische Diskussion (Komposition versus Vererbung etc.) erscheint mir wie eine Ablenkung vom gesunden Menschenverstand (mit dem Vorteil im Nachhinein - fast 3 Jahre später immer noch ungelöst). Offensichtlich wird es von Leuten benötigt, die Docker-Compose weiterhin verwenden könnten.

+1 :+1:

Ich habe diese Funktion zuvor intensiv für dev / test / ci Umgebungen verwendet, in denen ich eine Compose-Datei in Unterverzeichnispfade von ./config/{dev,test,ci}/compose.yaml . Ich hätte ein .env mit COMPOSE_ENV=dev , aber Entwickler könnten überschreiben, und natürlich würde ich in ci überschreiben.

Ich bin schockiert, dass ich die Funktion verworfen habe und sie nicht durch etwas ersetzt habe, das etwas Ähnliches kann. Vielleicht erlauben Sie uns einfach, jinja2 zu verwenden und zu tun, was wir wollen. Ich hoffe, Docker-Compose wäre weniger Anti-DRY. :'(

Scheint, dass extends von docker-compose seit v1.27 (https://github.com/docker/compose/pull/7588) unterstützt wird.

Ein Anwendungsfall, in dem ich die Funktion intensiv verwende, besteht darin, Docker-Images für Code zu versionieren. Meine docker-dev- und prod-compose-Dateien erstrecken sich beide von docker-images.yml, wo nur der Basisdienst aufgeführt ist und eine mit Tags versehene Version des Abbilds des Dienstes.

Habe in v3 keine einfache Problemumgehung dafür gefunden.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen