web-dev-qa-db-ja.com

docker runコマンドを使用して、DockerfileのCMDに引数を渡します

私はDockerが初めてであり、Dockerコンテナーを希望どおりにセットアップするのに苦労しています。 nodejsアプリは起動時に2つのパラメーターを取ることができます。たとえば、私は使用できます

node server.js 0 dev

または

node server.js 1 prod

本番モードと開発モードを切り替えて、クラスターをオンにする必要があるかどうかを判断します。今、私は同様のことを行うための引数を持つドッカー画像を作成したいと思います、これまでにできる唯一のことは、Dockerfileを調整してラインを作ることです

CMD [ "node", "server.js", "0", "dev"]

そして

docker build -t me/app .は、Dockerを構築します。

次に、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

イメージを作成し、「environment」引数と「cluster」引数を指定してnodejsコマンドを実行するため、Dockerfileを変更してドッカーを再構築する必要はありません。どうすればこれを達成できますか?

29
Jaaaaaaay

Dockerfileが環境変数を宣言していることを確認してください with ENV

ENV environment default_env_value
ENV cluster default_cluster_value

ENV <key> <value>フォームは inplaced inline にできます。

それから docker runで環境変数を渡す

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}"]

説明は、シェルはDockerではなく環境変数を展開する責任があるということです。 JSON構文を使用する場合、コマンドがシェルをバイパスして直接実行されることを明示的に要求しています。

Builder RUN と同じ考え方(CMDにも適用):

シェルフォームとは異なり、execフォームはコマンドシェルを呼び出しません。
これは、通常のシェル処理が行われないことを意味します。

たとえば、RUN [ "echo", "$HOME" ]$HOMEの変数置換を行いません。シェル処理が必要な場合は、Shellフォームを使用するか、シェルを直接実行します(例:RUN [ "sh", "-c", "echo $HOME" ])。

Execフォームを使用し、シェルフォームの場合のように直接シェルを実行する場合、環境変数の展開を行うのはドッカーではなくシェルです。

45
VonC

もう1つのオプションは、 ENTRYPOINT を使用してnodeを実行する実行可能ファイルに指定し、 CMD を使用して引数を指定することです。ドキュメントには、 実行形式ENTRYPOINTの例 の例があります。

このアプローチを使用すると、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コンテナーを誤って起動することはありません。

29
R0MANARMY

Dockerコンテナーでこれを行う一般的な方法は、環境変数を渡すことです。

docker run -p 9000:9000 -e NODE_ENV=dev -e CLUSTER=0 -d me/app
4
Paul