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

Внутри моего файла Docker:

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

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

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

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

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

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

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

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

CMD django-admin startproject $PROJECTNAME

Ответ 2

Допустим, вы хотите запустить 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 "[email protected]")

Ответ 3

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

Пример:

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

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

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

Ответ 4

В эти дни я сталкиваюсь с той же проблемой. Например, CMD exec/$name дает ответ /bin/sh: exec: строка 1:/: Permission denied, $ name - переменная. В таком случае я делаю $ name a ОКРУЖАЮЩЕЙ СРЕДОЙ как $ NAME, тогда это нормально с CMD exec/$NAME.