Как я могу использовать переменную внутри Dockerfile CMD?


112

Внутри моего Dockerfile:

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

Ошибка:

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

Какой здесь самый быстрый обходной путь? Есть ли у Docker какие-либо планы по «исправлению» или внедрению этой функции в более поздних версиях Docker?

ПРИМЕЧАНИЕ. Если я удалю строку CMD из файла Docker, а затем запустил контейнер Docker, я смогу вручную запустить Django-admin startproject $ PROJECTNAME изнутри контейнера, и он создаст проект ...


1
Как и когда вы определяете $PROJECTNAME?
Piotr Wittchen

В начале моего Dockerfile с использованием ENV. Также я забыл упомянуть, что если я удалю строку CMD из Dockerfile, а затем запустил контейнер, я могу запустить эту команду изнутри контейнера, и она создаст проект (что означает, что переменная ENV действительна).
Дэвид

Какой тип переменной вы имеете в виду: переменную dockerfile или переменную среды (как во время выполнения вашей системы)?
emix 06

Ответы:


171

Когда вы используете список выполнения, как в ...

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

... тогда Docker выполнит данную команду напрямую , без использования оболочки. Поскольку оболочка не используется, это означает:

  • Без расширения переменных
  • Без подстановочных знаков
  • Нет Перенаправление ввода / вывода с >, <, |и т.д.
  • Нет нескольких команд через command1; command2
  • И так далее.

Если вы хотите, CMDчтобы переменные расширялись, вам нужно организовать оболочку. Сделать это можно так:

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

Или вы можете использовать простую строку вместо списка выполнения, что даст вам результат, во многом идентичный предыдущему примеру:

CMD django-admin startproject $PROJECTNAME


21

Если вы хотите использовать значение во время выполнения, установите ENVзначение в Dockerfile. Если вы хотите использовать его во время сборки, вам следует использовать ARG.

Пример :

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

Передайте значение в команде сборки:

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

12

Допустим, вы хотите запустить Java-процесс внутри контейнера:

Пример отрывка из Dockerfile:

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

Пример отрывка из entrypoint.sh:

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

0

Вдохновленный вышесказанным, я сделал следующее:

#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 && \ 
       .....
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.