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
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.
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.
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
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
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.
Als Ergänzung zur Antwort von @ DarkSideF können Sie die folgende Problemumgehung verwenden, wenn Sie das Ergebnis eines vorherigen Befehls in Ihrer Dockerfile
während des Buildprozesses wiederverwenden möchten:
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.