Compose: Verwenden des Shell-Befehls in docker-compose.yml

Erstellt am 27. Okt. 2016  ·  41Kommentare  ·  Quelle: docker/compose

Hallo, gibt es eine Möglichkeit, Shell-Befehle in der Datei docker-compose.yml verwenden?
Hier ist mein Anwendungsfall:

 version: '2'
 services:
   ci:
     image: jenkins
     volumes:
       - ./data:/var/jenkins_home
       - /var/run/docker.sock:/var/run/docker.sock
       - $(command -v docker):/usr/bin/docker
     groupadd:
       - $(stat -c %g /var/run/docker.sock)
     ports:
       - "8080:8080"
       - "50000:50000"

Derzeit gibt es mir diesen Fehler:

ERROR: Invalid interpolation format for "volumes" option in service "ci": "${command -v docker}:/usr/bin/docker"
kinquestion

Hilfreichster Kommentar

Das wäre sehr nützlich zu haben ....

Alle 41 Kommentare

Hallo @zkanda ,

Entschuldigung, das unterstützen wir nicht. In der Regel wird dazu Umgebungsvariablen festgelegt und stattdessen die Variablensubstitution in der Compose-Datei verwendet.

@ shin- danke, ich kann mit Umgebungsvariablen umgehen. Auch .env scheint sehr nützlich zu sein.
Relevante Dokumente: https://docs.docker.com/compose/environment-variables/#/the -env-file

@zkanda hast du das jemals zum .env Datei versucht

DOCKER_BIN=`which docker`

und dann in der docker-compose.yml

jenkinsmaster:
  build: jenkins-master
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ${DOCKER_BIN}:/usr/bin/docker
  ports:
    - "50000:50000"

Aber ich bekomme immer

Cannot create container for service jenkinsmaster: create `which docker`: "`which docker`" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed.

Es sieht also so aus, als würden Befehle als Zeichenfolgen in der Datei .env interpretiert?

Befehle werden nicht durch Verfassen, in .env oder anderswo erweitert.

Das wäre sehr nützlich zu haben ....

+1

Hier ist ein Anwendungsfall. Beim Einrichten von Kafka wird die IP des Host-Computers benötigt. Ich habe das folgende Skript, um das für mich zu bekommen:

DOCKER_HOST_IP=$(ifconfig | grep 'inet .*br' | sed -E 's/.*inet (.*) netmask.*/\1/')

Ich verweise auf diese IP in der Umgebung. Ich kann nicht mehr einfach docker-compose up ausführen, weil ich das vorher ausführen muss. Und ich muss die anderen Entwickler im Team darüber informieren.

+1

Wäre nützlich, um den aktuellen Benutzer zu erhalten, wie in:

services:
  foo:
    image: bar:latest
    user: ${CURRENT_USER-$(id -u):$(id -g)}

Es muss auch andere Anwendungsfälle geben ...

Übrigens verstehe ich nicht, dass ${BAZ-default} in Compose funktioniert, wenn wir den Rest der Bash-Funktionen nicht ausführen können ... (soweit ich weiß, die - ist eine der variablen Manipulationsfunktionen von Bash, beispielsweise durch Ersetzen durch ${VAR/search/replace} )

Ja @ davi5e ... Was ich versucht habe:

version: "3.7"

services:
  orchestrator:
    build: .
    ports:
      - "2000:2000"
    # Use type host until we can test link
    network_mode: "host"
    environment:
      - NODE_ENV=development
      - LOCAL_USER_ID=${id -u}

@ davi5e Ein weiterer Anwendungsfall ist, wenn Sie ein Docker-Volume erstellen und es mit Ihrem Git-Repository-Verzeichnis verknüpfen möchten. Dieses absolute Bad wird für jeden Entwickler im Team vorsichtig sein.

+1
Bitte öffnen Sie das Problem erneut

+1
Mein Anwendungsfall ist es, eine Reihe von Ports zu veröffentlichen, die als Funktion eines "Basis" -Ports bestimmt werden

Dies wäre sehr nützlich, um UID / GID-Variablen festzulegen, da dies so ziemlich eine Voraussetzung für die Verwendung von Docker in einer Entwicklungsumgebung ist (ohne dass Skripte verwendet werden müssen, um dies in eine ENV-Datei zu setzen).

+1

Könnte dies verwenden, um die von Docker erzeugten Bilder mit dem Git-Tag zu kennzeichnen / zu kennzeichnen und Hash zu festschreiben:

In .env :

GIT_VERSION=$(git describe --always --dirty --abbrev)
OUTER_PORT=6970

In docer-complse.yml :

version: '3'
services:
  nginx:
    restart: always
    build:
        context: ./nginx
        labels:
          org.label-schema.schema-version: "1.0"
          org.label-schema.version: "${GIT_VERSION}"
          org.lavel.schema.url: "https://mydocu-server.company.com/vcs/${GIT_VERSION}"
    ports:
      - ${OUTER_PORT}:8080

Wenn Ihre Shell in der Entwicklung die Variable UID festlegt, können Sie diese beim Erstellen des lokalen Entwicklungsimages übergeben. Da das lokale Entwicklungsimage nicht freigegeben wird, müssen Sie sich keine Sorgen über UID-Konflikte mit Ihren Mitarbeitern machen.

+1

@ con-f-use Wenn dies nur den eigentlichen Befehl und nicht das Ergebnis meiner Tests sendet, ist der einzige Hack, den ich bisher erfolgreich war, das Schreiben eines Skriptumbruch-Docker-Compos, der die Umgebungsvariable einrichtet.

+1

TL; DR, wenn Sie diese Variablen aus der Datei .env exportieren möchten:

# set the path of .env file here
ENV_FILE="${ENV_FILE:-local.env}"
while IFS= read -r line; do
  export "$line"
done < <( grep --color=never -E -v -e '^#' -e '^[[:space:]]*$' "${ENV_FILE}" )

Wie benutzt man:

  • Geben Sie es in Ihre Befehlszeile ein und drücken Sie die Eingabetaste, um Ihre aktuelle Shell-Umgebung zu ändern

ODER

  • Speichern Sie es als Bash-Skript und geben Sie es als Quelle an

Vorsichtsmaßnahmen:

  • Wenn Sie dies als Skript speichern und ausführen, werden diese Variablen in Ihrer aktuellen Shell-Umgebung nicht auf magische Weise exportiert. Sie müssen es beschaffen oder ausgefallene eval .
  • (Vielleicht eine gute Sache?) Bestehende Variablen mit demselben Namen werden in $ENV_FILE überschrieben

Erklärung: hier

Schauen Sie sich direnv an, um all das zu automatisieren. Https://direnv.net/

Am Fr, 28. Juni 2019, 12:57 Uhr Sudarshan Wadkar [email protected]
schrieb:

TL; DR, wenn Sie diese Variablen aus der ENV-Datei exportieren möchten:

Legen Sie hier den Pfad der ENV-Datei fest

ENV_FILE = "$ {ENV_ FILE: -local.env }", während IFS = -r Zeile lesen; tun
exportiere "$ line" fertig << (grep --color = nie -E -v -e '^ #' -e '^ [[: space:]] * $' "$ {ENV_FILE}")

Wie benutzt man:

  • Geben Sie es in Ihre Befehlszeile ein
  • Speichern Sie es als Bash-Skript und geben Sie es als Quelle an

Vorsichtsmaßnahmen:

  • Wenn Sie dies als Skript speichern und ausführen, werden diese nicht auf magische Weise exportiert
    Variablen in Ihrer aktuellen Shell-Umgebung. Sie müssen es beschaffen oder tun
    eine ausgefallene Bewertung.
  • (Vielleicht eine gute Sache?) Bestehende Variablen werden damit überschrieben
    Name in $ ENV_FILE

Erklärung: hier
https://explainshell.com/explain?cmd=while+IFS%3D+read+-r+line%3B+do+export+%22%24line%22%3B+done+%3C+%3C%28grep+--color%3Dno+ -v + -e + 27% 5E% 23% 27 + -e + 27% 5E% 5B% 5B% 3Aspace% 3A% 5D% 5D *% 24% 27 +% 24% 7BENV_FILE% 7D% 29

- -
Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/docker/compose/issues/4081?email_source=notifications&email_token=AACHRDBQXQZTC5FXTOFL6UTP4XOBJA5CNFSM4CUISSSKYY3PNVWWK3TUL52HS4DFVREXG43WMZM
oder schalten Sie den Thread stumm
https://github.com/notifications/unsubscribe-auth/AACHRDGJ6FAQBEDLBSRVS6TP4XOBJANCNFSM4CUISSSA
.

Ja, direnv ist nett, aber ich bin mir nicht sicher, ob es mit Dockers .env -Datei nützlich sein wird, die einfache Zeilen mit einfacher VAR=VAL -Syntax enthält (gemäß diesem Link) Die Idee, eine .env -Datei zu sein, wird an das Repository übergeben, und das Build-Skript kann sie auf meinem lokalen Computer ausführen oder docker-compose kann sie auf dem Staging / Deployment ausführen.

Es gibt nicht wirklich Umgebungsvariablen
https://en.wikipedia.org/wiki/Environment_variable, wenn sie Teil von sind
die Codebasis und nicht Teil der Umgebung ...

Am Fr, 28. Juni 2019 um 14:04 Uhr Sudarshan Wadkar [email protected]
schrieb:

Ja, direnv ist nett, aber ich bin mir nicht sicher, ob es bei Docker nützlich sein wird
.env-Datei mit einfachen Zeilen mit einfacher VAR = VAL-Syntax (gemäß dieser
https://docs.docker.com/compose/env-file/#syntax-rules link.) Die Idee
Als ENV-Datei wird das Repository festgeschrieben und das Build-Skript kann
Führen Sie es auf meinem lokalen Computer aus, oder Docker-Compose kann es auf dem Staging / Deploy ausführen.

- -
Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/docker/compose/issues/4081?email_source=notifications&email_token=AACHRDCEKOMK2VI3A43QBC3P4XV5BA5CNFSM4CUISSSKYY3PNVWWK3TUL52HS4DFVREXG43ZMW
oder schalten Sie den Thread stumm
https://github.com/notifications/unsubscribe-auth/AACHRDF3Q3YOZPHUIUZYEPTP4XV5BANCNFSM4CUISSSA
.

Oh ok.

Ich denke gerne, dass die Datei .env in eine Umgebungsvariable umgewandelt wird, wenn Sie docker-compose up ausführen.

Mein Anwendungsfall bestand darin, dieselbe .env -Datei als Quelle der Wahrheit zu verwenden, um eine lokale Entwicklungsinstanz auszuführen (möglicherweise ohne Hilfe von docker-compose ). Also ja, vielleicht sind diese Zeilen in der Datei .env keine wirklichen Umgebungsvariablen, aber sie werden beim Bereitstellen sicherlich zu einer.

Ich sehe immer noch nicht, wie direnv in diesem Fall helfen wird.

Ein weiterer Anwendungsfall besteht darin, einen Befehl, der ein Kennwort generiert, das es env var zuweist, in den Container einzufügen.
Auf diese Weise würde das Passwort nicht in .env- oder docker-compose.yml-Dateien geschrieben.

Ich denke, dies wird ein großer Vorteil für viele sicherheitsrelevante Anwendungsfälle sein.

+1

+1

+1 wäre äußerst nützlich, um uid und gid ohne die Lösung zu komplizieren

`` `
/ _ / \
(oo)

^ <`` `

+1 Ich habe einen Anwendungsfall wie oben erwähnt, um einen Git-Zweig hinzuzufügen und in der Compose-Datei festzuschreiben, die schließlich in die Docker-Datei aufgenommen und dann als Version im Manifest des JARs hinzugefügt wird, das in einer Phase eines mehrstufigen Docker-Erstellungsprozesses erstellt wurde .

  gateway:
    image: name
    build:
      context: ./project
      dockerfile: build/Dockerfile
      args:
        - GIT_COMMIT=${$(git rev-list -1 HEAD):-unspecified}
        - GIT_DATE=${$(git log -1 --date=short --pretty=format:%ct):-unspecified}

Derzeit muss ich für 7 Projekte in meiner Erstellungsdatei 7x2-Umgebungen festlegen. Traurig.

@ shin- Könnten Sie dies als Feature-Anfrage erneut öffnen? Es scheint, als ob es nicht durch nette Umgehungslösungen gelöst wurde, und es besteht ein solider Bedarf dafür.

+1 Wahrscheinlich hätte dies auf andere Weise erreicht werden können, aber ich musste die Docker-Engine aus einem Container heraus aktivieren, um einen benachbarten Container neu zu starten. In dem Fall, in dem mein Letsencrypt-Zertifikat abgelaufen ist, muss ich den NGinx-Container nach der Erneuerung neu starten. Das Problem ist, wie kann ich Docker-Compose im Container mitteilen, wie der Projektname für diese Gruppe von Containern lautet? PROJECT=(basedir ~+) . Es ist vorerst manuell codiert :(

+1 auf diese Funktionsanforderung
Ein weiterer Anwendungsfall besteht darin, Geheimnisse aus einem CLI / http (z. B. Tresor, 1Password) abzurufen und sich in die Umgebung einzufügen.
dh

...
    environment:
      - SERVICE_USERNAME=$(vault kv get -field=username kv/service/credentials)
      - SERVICE_PASSWORD=$(vault kv get -field=password kv/service/credentials)
...

Ich habe das gleiche Bedürfnis wie @rafaelbattesti , außer dass ich lastpass benutze.

...
     environment:
         - TRPASSWD=$(lpass show --password Transmission)
....

+1

+1

@ shin- Könnten Sie dies als Feature-Anfrage erneut öffnen? Es scheint, als ob es nicht durch nette Umgehungslösungen gelöst wurde, und es besteht ein solider Bedarf dafür.

@ four43 , vielleicht @ shin- oder andere lesen keine Kommentare zu geschlossenen Themen? Sollen wir noch einen öffnen, um Aufmerksamkeit zu bekommen?

Die Variablenerweiterung in der Docker-Compose-Datei wäre eine sehr nützliche Funktion ...

+1

@esale - Ja, ich denke, es hängt irgendwie davon ab. Ich konnte sehen, dass es für diesen Fall nicht möglich war. Gehen Sie bei DSL nicht zu viel über Bord. An diesem Punkt Vorlage die Docker-Compose-Datei mit einem anderen Tool? Überqueren wir Bedenken zu sehr?

Wenn Sie eine .env-Datei verwenden, können Sie die Shell-Ausgabe durch einen Befehl wie diesen ersetzen

eval "echo \"$(cat .env.example)\"" > .env

Beispiel .env.example Datei

DOCKER_BIN=$(which docker)
DOCKER_COMPOSE_BIN=$(which docker-compose)

Erstellen Sie die .env-Datei

DOCKER_BIN=/snap/bin/docker
DOCKER_COMPOSE_BIN=/snap/bin/docker-compose
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen