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.