Wie kann ich eine Variable in einem Dockerfile-CMD verwenden?

99

In meiner Docker-Datei:

ENV PROJECTNAME mytestwebsite
CMD ["django-admin", "startproject", "$PROJECTNAME"]

Error:

CommandError: '$PROJECTNAME' is not a valid project name

Was ist hier die schnellste Problemumgehung? Hat Docker Pläne, diese Funktionalität in späteren Versionen von Docker zu "reparieren" oder einzuführen?

HINWEIS: Wenn ich die CMD-Zeile aus der Docker-Datei entferne und dann den Docker-Container ausführe, kann ich das Django-admin-Startprojekt $ PROJECTNAME manuell aus dem Container heraus ausführen und das Projekt erstellen ...

David
quelle
1
Wie und wann definieren Sie $PROJECTNAME?
Piotr Wittchen
Zu Beginn meiner Docker-Datei mit ENV. Außerdem habe ich vergessen zu erwähnen, dass ich diesen Befehl ausführen kann, wenn ich die CMD-Zeile aus der Docker-Datei entferne und dann den Container ausführe. Dadurch wird das Projekt erstellt (dh die ENV-Variable ist gültig).
David
Welche Art von Variable meinen Sie: Docker-Datei-Variable oder Umgebungsvariable (wie in Ihrer Systemlaufzeit)?
Emix

Antworten:

157

Wenn Sie eine Ausführungsliste verwenden, wie in ...

CMD ["django-admin", "startproject", "$PROJECTNAME"]

... dann führt Docker den angegebenen Befehl direkt aus , ohne eine Shell einzubeziehen. Da keine Shell beteiligt ist, bedeutet dies:

  • Keine variable Erweiterung
  • Keine Platzhaltererweiterung
  • Nein i / o - Umleitung mit >, <, |, usw.
  • Keine Mehrfachbefehle über command1; command2
  • Und so weiter.

Wenn Sie CMDVariablen erweitern möchten , müssen Sie eine Shell einrichten. Sie können das so machen:

CMD ["sh", "-c", "django-admin startproject $PROJECTNAME"]

Oder Sie können eine einfache Zeichenfolge anstelle einer Ausführungsliste verwenden, wodurch Sie ein Ergebnis erhalten, das weitgehend mit dem vorherigen Beispiel identisch ist:

CMD django-admin startproject $PROJECTNAME
Larsks
quelle
2
Weitere Informationen finden Sie in Dockers Issue-Tracker: github.com/docker/docker/issues/5509
jannis
@ Larsks eine einfache Zeichenfolge ist erstaunlich
Abdoutelb
Du hast meinen Tag gerettet!
Supratim Roy
18

Wenn Sie den Wert zur Laufzeit verwenden möchten, legen Sie den ENVWert in der Dockerfile. Wenn Sie es zur Erstellungszeit verwenden möchten, sollten Sie es verwenden ARG.

Beispiel:

ARG value
ENV envValue=$value
CMD ["sh", "-c", "java -jar ${envValue}.jar"]

Übergeben Sie den Wert im Befehl build:

docker build -t tagName --build-arg value="jarName"
rex roy
quelle
10

Nehmen wir an, Sie möchten einen Java-Prozess in einem Container starten:

Beispiel Dockerfile-Auszug:

ENV JAVA_OPTS -XX +UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -XshowSettings:vm 
... 
ENTRYPOINT ["/sbin/tini", "--", "entrypoint.sh"] 
CMD ["java", "${JAVA_OPTS}", "-myargument=true"]

Beispiel entrypoint.sh Auszug:

#!/bin/sh 
... 
echo "*** Startup $0 suceeded now starting service using eval to expand CMD variables ***"
exec su-exec mytechuser $(eval echo "$@")
Flavio Aiello
quelle
0

Inspiriert von oben habe ich Folgendes getan:

#snapshot by default. 1 is release.
ENV isTagAndRelease=0

CMD     echo is_tag: ${isTagAndRelease} && \
        if [ ${isTagAndRelease} -eq 1 ]; then echo "release build"; mvn -B release:clean release:prepare release:perform; fi && \
        if [ ${isTagAndRelease} -ne 1 ]; then echo "snapshot build"; mvn clean install; fi && \ 
       .....
csomakk
quelle