Использование команды "выполнить" докер для передачи аргументов в cmd в файла Docker
Я новичок в Docker, и мне трудно настроить контейнер docker, как я хочу. У меня есть приложение nodejs может принимать два параметра при запуске. Например, я могу использовать
node server.js 0 dev
или
node server.js 1 prod
для переключения между производственным режимом и режимом dev и определения, следует ли включить кластер. Теперь я хочу создать образ docker с аргументами, чтобы сделать аналогичную вещь, единственное, что я могу сделать, это настроить Dockerfile на есть строка
CMD [ "node", "server.js", "0", "dev"]
и
docker build -t me/app .
построить докер.
затем docker run -p 9000:9000 -d me/app
для запуска докера.
но если я хочу переключиться в режим prod, мне нужно изменить Dockerfile CMD на
CMD [ "node", "server.js", "1", "prod"]
,
и мне нужно убить старого, слушающего порт 9000 и восстановить изображение. Я хотел бы иметь что-то вроде
docker run -p 9000:9000 environment=dev cluster=0 -d me/app
чтобы создать изображение и запустить nodejs команда с аргументами" environment "и" cluster", поэтому мне больше не нужно изменять Dockerfile и перестраивать docker. Как я могу это сделать?
3 ответов
убедитесь, что ваш Dockerfile объявляет переменную среды С ENV
:
ENV environment default_env_value
ENV cluster default_cluster_value
на ENV <key> <value>
форма может быть заменено inline.
тут вы можете передать переменную среды с помощью docker run
docker run -p 9000:9000 -e environment=dev -e cluster=0 -d me/app
или установите их через файл compose:
node:
environment:
- environment=dev
- cluster=0
Вашего Файла Docker CMD
можно использовать эту переменную среды, но, как указано в вопрос 5509, вам нужно сделать так sh -c
форма:
CMD ["sh", "-c", "node server.js ${cluster} ${environment}"]
объяснение заключается в том, что оболочка отвечает за расширение переменных среды, а не Docker. Когда вы используете синтаксис JSON, вы явно запрашиваете, чтобы ваша команда обходила оболочку и выполнялась напрямую.
та же идея с Builder RUN (относится к CMD
так же):
в отличие от оболочки форма, форма exec не вызывает командную оболочку.
Это означает, что нормальной обработки оболочки не происходит.например,
RUN [ "echo", "$HOME" ]
не будет выполнять подстановку переменных на$HOME
. Если вы хотите обработать оболочку, используйте форму оболочки или выполните оболочку напрямую, например:RUN [ "sh", "-c", "echo $HOME" ]
.при использовании формы exec и непосредственном выполнении оболочки, как в случае с формой оболочки, именно оболочка выполняет среду переменное расширение, а не докер.
другой вариант-использовать ENTRYPOINT
указывает, что node
является исполняемым файлом для запуска и CMD
предоставить аргументы. Документов пример Exec form ENTRYPOINT example.
используя этот подход, ваш Dockerfile будет выглядеть примерно так:
FROM ...
ENTRYPOINT [ "node", "server.js" ]
CMD [ "0", "dev" ]
запуск его в dev будет использовать ту же команду
docker run -p 9000:9000 -d me/app
и запустив его в prod, вы передадите параметры в run команда
docker run -p 9000:9000 -d me/app 1 prod
вы можете опустить CMD
полностью и всегда проходят в 0 dev
или 1 prod
в качестве аргументов для команды run. Таким образом, вы случайно не запускаете контейнер prod в dev или контейнер dev в prod.
типичный способ сделать это в контейнерах Docker-передать переменные среды:
docker run -p 9000:9000 -e NODE_ENV=dev -e CLUSTER=0 -d me/app