Come posso utilizzare una variabile all'interno di un Dockerfile CMD?


104

All'interno del mio Dockerfile:

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

Errore:

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

Qual è la soluzione più rapida qui? Docker ha in programma di "riparare" o introdurre questa funzionalità nelle versioni successive di Docker?

NOTA: se rimuovo la riga CMD dal file Docker e quindi eseguo il contenitore Docker, sono in grado di eseguire manualmente Django-admin startproject $ PROJECTNAME dall'interno del contenitore e creerà il progetto ...


1
Come e quando stai definendo $PROJECTNAME?
Piotr Wittchen

All'inizio del mio Dockerfile usando ENV. Inoltre ho dimenticato di dire che se rimuovo la riga CMD dal Dockerfile e poi eseguo il container, dall'interno del container posso eseguire questo comando e creerà il progetto (il che significa che la variabile ENV è valida).
david

Che tipo di variabile intendi: variabile dockerfile o variabile ambientale (come nel runtime del tuo sistema)?
emix

Risposte:


164

Quando usi un elenco di esecuzione, come in ...

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

... quindi Docker eseguirà direttamente il comando dato , senza coinvolgere una shell. Poiché non è coinvolta alcuna shell, ciò significa:

  • Nessuna espansione variabile
  • Nessuna espansione con caratteri jolly
  • No redirezione I / O con >, <, |, ecc
  • Nessun comando multiplo tramite command1; command2
  • E così via.

Se vuoi CMDespandere le variabili, devi organizzare una shell. Puoi farlo in questo modo:

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

Oppure puoi usare una semplice stringa invece di un elenco di esecuzione, che ti dà un risultato in gran parte identico all'esempio precedente:

CMD django-admin startproject $PROJECTNAME

2
Qualche lettura in più nel tracker dei problemi di Docker: github.com/docker/docker/issues/5509
jannis

@larsks una semplice stringa è INCREDIBILE
abdoutelb

Mi hai salvato la giornata!
Supratim Roy

18

Se si desidera utilizzare il valore in fase di esecuzione, impostare il ENVvalore nel file Dockerfile. Se vuoi usarlo in fase di compilazione, dovresti usare ARG.

Esempio :

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

Passa il valore nel comando build:

docker build -t tagName --build-arg value="jarName"

10

Diciamo che vuoi avviare un processo java all'interno di un contenitore:

Esempio di estratto Dockerfile:

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

Estratto entrypoint.sh di esempio:

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

0

Ispirato sopra, ho fatto questo:

#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 && \ 
       .....
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.