Як я можу використовувати змінну всередині CMD Dockerfile?


104

Усередині мого 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 з файлу Docker, а потім запущу контейнер, зсередини контейнера я можу запустити цю команду, і вона створить проект (тобто змінна ENV дійсна).
Девід

Який тип змінної ви маєте на увазі: змінну dockerfile чи змінну середовища (як під час виконання вашої системи)?
emix

Відповіді:


164

Коли ви використовуєте список виконання, як у ...

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

... тоді Docker виконає задану команду безпосередньо , не залучаючи оболонку. Оскільки жодна оболонка не задіяна, це означає:

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

Якщо ви хочете, щоб ваше CMDрозширення змінних, вам потрібно домовитись про оболонку. Ви можете зробити це так:

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

Або ви можете використовувати простий рядок замість списку виконання, що дає вам результат, ідентичний попередньому прикладу:

CMD django-admin startproject $PROJECTNAME

2
Ще трохи прочитання в трекері випусків
jannis

@larsks простий рядок ДИВУЄ
abdoutelb

Ти врятував мій день!
Супратим Рой

18

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

Приклад:

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

Передайте значення в команді build:

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

10

Скажімо, ви хочете запустити процес Java усередині контейнера:

Приклад виписки з файлу Docker:

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.