Können wir ENV-Variablen durch die cmd-Zeile übergeben, während wir ein Docker-Image über die Docker-Datei erstellen?

77

Ich arbeite an einer Aufgabe, bei der ein Docker-Image mit centOs als Basis mithilfe einer Docker-Datei erstellt wird . Für einen der Schritte in der Docker- Datei müssen die ENV-Variablen http_proxy und https_proxy festgelegt werden, damit sie hinter dem Proxy arbeiten können.

Da diese Docker-Datei von mehreren Teams mit unterschiedlichen Proxys verwendet wird, möchte ich vermeiden, dass die Docker-Datei für jedes Team bearbeitet werden muss. Stattdessen suche ich nach einer Lösung, mit der ich ENV-Variablen zur Erstellungszeit übergeben kann, z.

sudo docker build -e http_proxy = irgendein Wert.

Ich bin mir nicht sicher, ob es bereits eine Option gibt, die dies bietet. Vermisse ich etwas

Aniketh
quelle
1
Was ist das Problem beim Übergeben dieser zur Laufzeit? So etwas wie docker run -e http_proxy http://1.2.3.4:3128 -e https_proxy 1.2.3.4:3129? Das Dokument von docker run docs.docker.com/reference/commandline/run
user2915097
2
Das Problem ist, dass einer der Schritte in der Docker-Datei die yum-Installation betrifft und fehlschlägt, wenn ich die http / https ENV-Variablen nicht setze und ohne ordnungsgemäße Installation das Image nicht erstellen kann. Daher hilft mir der Docker-Lauf hier nicht.
Aniketh
Ich fürchte, Sie müssen bestimmte Images erstellen. Der einzige Unterschied besteht darin, dass die Werte von http_proxy (s) ONBUILD möglicherweise hilfreich sind. Ich befürchte jedoch, dass dies hier nicht geeignet ist (siehe doc docs.docker.com/reference/builder
user2915097)
Dies wurde hier diskutiert github.com/docker/docker/issues/4962 und wieder hier github.com/docker/docker/pull/9176 und geschlossen, so dass es im Moment scheint, dass Sie keine Lösung haben
user2915097
Vielen Dank an user2915097 für Ihre Kommentare. Ich habe die obigen Github-Links bereits durchgesehen und diese Frage mit der winzigen Hoffnung gestellt, dass jemand auf Stackoverflow mit dieser ähnlichen Situation konfrontiert sein könnte.
Aniketh

Antworten:

119

Container können mit build arguments(in Docker 1.9+) erstellt werden, die wie Umgebungsvariablen funktionieren.

Hier ist die Methode:

FROM php:7.0-fpm
ARG APP_ENV=local
ENV APP_ENV ${APP_ENV}
RUN cd /usr/local/etc/php && ln -sf php.ini-${APP_ENV} php.ini

und dann einen Produktionscontainer bauen:

docker build --build-arg APP_ENV=prod .

Für Ihr spezielles Problem:

FROM debian
ENV http_proxy ${http_proxy}

und dann ausführen:

docker build --build-arg http_proxy=10.11.24.31 .

Beachten Sie, dass Sie beim Erstellen Ihrer Container mit diesen Build-Argumenten in der Datei angebendocker-compose können , jedoch nicht in der Befehlszeile. Sie können jedoch die Variablensubstitution in der Datei verwenden, die Umgebungsvariablen verwendet .docker-compose.ymldocker-compose.yml

Sin30
quelle
8
Weil ich es übersehen habe: ARG muss Docker mitteilen, dass ein Build-Argument an den Builder übergeben werden kann. Ohne Angabe von ARG <Name> funktioniert es nicht.
Markus Bruckner
4
Dies ENV APP_ENV ${APP_ENV}wird nicht benötigt. Es ist genug, um darauf zu ARG APP_ENVverzichten, =localund es greift nach dem Build-Argument und verwendet es als eine beliebige Variable, die vonENV
ElmoVanKielmo,
3
@ElmoVanKielmo Das stimmt während des Builds, wird aber ARGnicht als Umgebungsvariable beibehalten , wenn das Docker-Image ausgeführt wird. Durch ENV APP_ENV ${APP_ENV}die Verwendung wird sichergestellt, dass die Umgebungsvariable weiterhin verfügbar ist, wenn der Container ausgeführt wird.
DuckPuppy
@ DuckPuppy stimmt, aber ich blieb bei der Frage des OP
ElmoVanKielmo
Bei der Frage von @ElmoVanKielmo OP geht es darum, die ENVBefehlszeile zu verlassen. Wie hilft es also, ARGallein zu sein? Sie müssen, ARGdamit Sie eine über übergeben können, --build-argund dann müssen Sie ENVsie in eine Umgebungsvariable kopieren, damit das Bild erhalten bleibt.
Haridsv
17

Also musste ich dies durch Ausprobieren herausfinden, da viele Leute erklären, dass Sie bestehen können ARG-> ENVaber es funktioniert nicht immer, da es sehr wichtig ist, ob das ARG vor oder nach dem FROMTag definiert wird.

Das folgende Beispiel sollte dies klar erklären. Mein Hauptproblem war ursprünglich, dass alle meine ARGS vorher definiert wurden, FROMwas dazu führte, dass alle ENVimmer undefiniert waren.

# ARGS PRIOR TO FROM TAG ARE AVAIL ONLY TO FROM for dynamic a FROM tag
ARG NODE_VERSION
FROM node:${NODE_VERSION}-alpine

# ARGS POST FROM can bond/link args to env to make the containers environment dynamic
ARG NPM_AUTH_TOKEN
ARG EMAIL
ARG NPM_REPO

ENV NPM_AUTH_TOKEN ${NPM_AUTH_TOKEN}
ENV EMAIL ${EMAIL}
ENV NPM_REPO ${NPM_REPO}

# for good measure, what do we really have
RUN echo NPM_AUTH_TOKEN: $NPM_AUTH_TOKEN && \
  echo EMAIL: $EMAIL && \
  echo NPM_REPO: $NPM_REPO && \
  echo $HI_5
# remember to change HI_5 every build to break `docker build`'s cache if you want to debug the stdout

..... # rest of whatever you want RUN, CMD, ENTRYPOINT etc..
Nick
quelle
3
WOW, verdammt, ist mir auch passiert! Niemand spricht darüber, nirgends in den Dokumenten wird erwähnt, gewarnt usw.! Danke vielmals!!!
Chrizzler
Könnte ich erwähnen, dass dies kritisch war, wenn Ihre Bereitstellungsumgebung aus automatischem CI stammt. IE Ich fand dies, als ich versuchte, gitlab CI so zu gestalten, dass es über Projektdomänen hinweg skaliert. IE Ein Projekt regelt möglicherweise eine andere Knotenversion usw.
Nick
2

Ich sah mich der gleichen Situation gegenüber.

Laut der Antwort von Sin30 ist die hübsche Lösung die Verwendung von Shell,

CMD ["sh", "-c", "cd /usr/local/etc/php && ln -sf php.ini-$APP_ENV php.ini"]
Tugrul
quelle