![](/img/trans.png)
[英]How can I Use Arguments in a Dockerfile with Yarn Workspaces (with CMD)?
[英]Use docker run command to pass arguments to CMD in Dockerfile
我是 Docker 新手,我很難根據需要設置 docker 容器。 我有一個 nodejs 應用程序在啟動時可以帶兩個參數。 例如,我可以使用
node server.js 0 dev
或者
node server.js 1 prod
在生產模式和開發模式之間切換並確定是否應該打開集群。 現在我想創建帶有參數的 docker 圖像來做類似的事情,到目前為止我唯一能做的就是調整 Dockerfile 有一條線
CMD [ "node", "server.js", "0", "dev"]
和
docker build -t me/app .
構建碼頭工人。
然后docker run -p 9000:9000 -d me/app
運行 docker。
但是如果我想切換到 prod 模式,我需要將 Dockerfile CMD 更改為
CMD [ "node", "server.js", "1", "prod"]
,
我需要殺死在端口 9000 上監聽的舊的並重建圖像。 我希望我能有類似的東西
docker run -p 9000:9000 environment=dev cluster=0 -d me/app
創建映像並使用“環境”和“集群”參數運行 nodejs 命令,因此我不需要更改 Dockerfile 並重新構建 docker。 我怎樣才能做到這一點?
確保您的 Dockerfile使用ENV
聲明環境變量:
ENV environment default_env_value
ENV cluster default_cluster_value
ENV <key> <value>
形式可以被inline 替換。
然后你可以使用 docker run 傳遞一個環境變量。 請注意,每個變量都需要一個特定的-e
標志才能運行。
docker run -p 9000:9000 -e environment=dev -e cluster=0 -d me/app
或者您可以通過您的撰寫文件設置它們:
node:
environment:
- environment=dev
- cluster=0
您的 Dockerfile CMD
可以使用該環境變量,但是,如issue 5509 中所述,您需要以sh -c
形式執行此操作:
CMD ["sh", "-c", "node server.js ${cluster} ${environment}"]
解釋是shell負責擴展環境變量,而不是Docker。 當您使用JSON 語法時,您明確要求您的命令繞過 shell 並直接執行。
與Builder RUN相同的想法(也適用於CMD
):
與 shell 形式不同,exec 形式不調用命令 shell。
這意味着不會發生正常的 shell 處理。
例如,
RUN [ "echo", "$HOME" ]
不會對$HOME
進行變量替換。 如果你想要 shell 處理,那么要么使用 shell 形式,要么直接執行 shell,例如:RUN [ "sh", "-c", "echo $HOME" ]
。
當使用 exec 形式並直接執行 shell 時,就像 shell 形式一樣,是 shell 進行環境變量擴展,而不是 docker。
另一種選擇是使用ENTRYPOINT
來指定該node
是要運行的可執行文件,並使用CMD
來提供參數。 文檔中有一個Exec 形式的示例 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 命令。 這樣你就不會意外地在 dev 中啟動一個 prod 容器或在 prod 中啟動一個 dev 容器。
在 Docker 容器中執行此操作的典型方法是傳入環境變量:
docker run -p 9000:9000 -e NODE_ENV=dev -e CLUSTER=0 -d me/app
選項 1) 使用 ENV 變量
文件
# we need to specify default values
ENV ENVIRONMENT=production
ENV CLUSTER=1
# there is no need to use parameters array
CMD node server.js ${CLUSTER} ${ENVIRONMENT}
運行 Docker
$ docker run -d -p 9000:9000 -e ENVIRONMENT=dev -e CLUSTER=0 -me/app
選項 2) 傳遞參數
文件
# use entrypoint instead of CMD and do not specify any arguments
ENTRYPOINT node server.js
運行 Docker
在 docker 鏡像名稱后傳遞參數
$ docker run -p 9000:9000 -d me/app 0 dev
有點偏離主題,存在構建參數以允許您在構建時傳入參數,這些參數顯示為環境變量,以在您的 docker 映像構建過程中使用:
$ docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .
不確定這是否有幫助,但我以這種方式使用它並且它的作用就像一個魅力
CMD ["node", "--inspect=0.0.0.0:9229", "--max-old-space-size=256", "/home/api/index.js"]
我在docker-compose 上發現這個沒有用燒瓶設置環境變量
docker-compose.yml
version: '2'
services:
app:
image: python:2.7
environment:
- BAR=FOO
volumes:
- ./app.py:/app.py
command: python app.py
應用程序
import os
print(os.environ["BAR"])
遲到了加入討論。 這是一個絕妙的技巧,您可以使用它來設置默認命令行參數,同時還支持用自定義參數覆蓋默認參數:
步驟#1 在您的 dockerfile 中調用您的程序,如下所示:
ENV DEFAULT_ARGS "--some-default-flag=123 --foo --bar"
CMD ["/bin/bash", "-c", "./my-nifty-executable ${ARGS:-${DEFAULT_ARGS}}"]
步驟#2 現在何時可以像這樣調用 docker-image:
# this will invoke it with DEFAULT_ARGS
docker run mydockerimage
# but this will invoke the docker image with custom arguments
docker run --env ARGS="--alternative-args --and-then-some=123" mydockerimage
您還可以調整此技術以執行更復雜的參數評估,但您認為合適。 Bash 支持多種單行結構來幫助您實現這一目標。
希望這項技術可以幫助那里的一些人節省幾個小時的時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.