webentwicklung-frage-antwort-db.com.de

Dockerfile - Setzt ENV auf das Befehlsergebnis

Ist es möglich, eine Docker-ENV-Variable auf das Ergebnis eines Befehls zu setzen? Wie:

ENV MY_VAR whoami

ich möchte, dass MY_VAR den Wert "root" erhält oder was auch immer whoami zurückgibt

41
Sultanen

Als Ergänzung zur DarkSideF-Antwort.

Sie sollten wissen, dass jede Zeile/jedes Kommando in Dockerfile in einem anderen Container ausgeführt wird.

Sie können so etwas tun:

RUN export bleah=$(hostname -f);echo $bleah;

Dies wird in einem einzigen Container ausgeführt.

12

Ich hatte das gleiche Problem und fand einen Weg, um Umgebungsvariable als Ergebnis einer Funktion festzulegen, indem Sie den Befehl RUN in dockerfile verwenden.

Zum Beispiel muss ich SECRET_KEY_BASE für die Rails-App nur einmal einstellen, ohne sich zu ändern, wie ich es beim Ausführen von:

docker run  -e SECRET_KEY_BASE="$(openssl Rand -hex 64)"

Stattdessen schreibe ich in Dockerfile:

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl Rand -hex 64)" >> /etc/bash.bashrc'

und meine env-Variable, die von root verfügbar ist, auch nach dem Bash-Login . oder möglicherweise

RUN /bin/bash -l -c 'echo export SECRET_KEY_BASE="$(openssl Rand -hex 64)" > /etc/profile.d/docker_init.sh'

dann ist diese Variable in CMD- und ENTRYPOINT-Befehlen verfügbar

Docker cache es als Layer und ändere es nur, wenn du einige Zeichenketten davor änderst.

Sie können auch verschiedene Möglichkeiten verwenden, um die Umgebungsvariable festzulegen.

9
DarkSideF

Zu diesem Zeitpunkt kann ein Befehlsergebnis mit RUN export verwendet werden, es kann jedoch keine ENV-Variable zugewiesen werden. 

Bekanntes Problem: https://github.com/docker/docker/issues/29110

7
Kur00Hazama

Diese Antwort ist eine Antwort auf @DarkSideF.

Die Methode, die er vorschlägt, ist folgende in Dockerfile:

RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl Rand -hex 64)" >> /etc/bash.bashrc'

(Hinzufügen eines Exports im /etc/bash.bashrc)

Es ist gut, aber die Umgebungsvariable ist nur für den Prozess /bin/bash verfügbar. Wenn Sie versuchen, Ihre Dockeranwendung beispielsweise für eine Node.js-Anwendung auszuführen, wird /etc/bash.bashrc vollständig ignoriert und Ihre Anwendung hat keinen einzigen Hinweis, was SECRET_KEY_BASE ist beim Versuch, auf process.env.SECRET_KEY_BASE zuzugreifen.

Dies ist der Grund, warum das Schlüsselwort ENV das ist, was jeder versucht, mit einem dynamischen Befehl zu verwenden, denn jedes Mal, wenn Sie Ihren Container ausführen oder einen Befehl exec verwenden, überprüft Docker ENV und leitet jeden Wert im gerade ausgeführten Prozess weiter (ähnlich wie -e).

Eine Lösung ist die Verwendung eines Wrappers (Verdienst @duglin in dieser github issue ) . Sie haben eine Wrapper-Datei (z. B. envwrapper) in Ihrem Projektstamm, die Folgendes enthält:

#!/bin/bash
export SECRET_KEY_BASE="$(openssl Rand -hex 64)"
export ANOTHER_ENV "hello world"
$*

und dann in deiner Dockerfile:

...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp
3
vdegenne

Ich bin mir nicht sicher, ob dies das ist, wonach Sie gesucht haben, aber um ENV-Variablen oder ARGS in Ihr .Dockerfile-Build einzufügen, funktioniert dieses Muster.

in deiner my_build.sh:

echo getting version of osbase image to build from
OSBASE=$(grep "osbase_version" .version | sed 's/^.*: //')

echo building docker
docker build -f \
--build-arg ARTIFACT_TAG=$OSBASE \
PATH_TO_MY.Dockerfile \
-t my_artifact_home_url/bucketname:$TAG .

zum Abrufen einer ARG in Ihrer .Docker-Datei könnte das Snippet folgendermaßen aussehen:

FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}

alternativ zum Abrufen einer ENV in Ihrer .Docker-Datei könnte das Snippet folgendermaßen aussehen:

FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}

die Idee ist, dass Sie das Shell-Skript ausführen, das die .Docker-Datei mit den Argumenten aufruft, die als Optionen für den Build übergeben wurden.

2
kat

Als Ergänzung zur Antwort von @ DarkSideF können Sie die folgende Problemumgehung verwenden, wenn Sie das Ergebnis eines vorherigen Befehls in Ihrer Dockerfilewährend des Buildprozesses wiederverwenden möchten:

  1. einen Befehl ausführen, das Ergebnis in einer Datei speichern
  2. verwenden Sie die Befehlssubstitution, um das vorherige Ergebnis dieser Datei in einen anderen Befehl zu übernehmen

Zum Beispiel :

RUN echo "bla" > ./result
RUN echo $(cat ./result)

Für etwas Reiniger können Sie auch das folgende Gist verwenden, das eine kleine CLI mit dem Namen envstore.py enthält:

RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)

Oder Sie können die Bibliothek python-dotenv verwenden, die eine ähnliche CLI hat.

0
sebpiq