私は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を変更してドッカーを再構築する必要はありません。どうすればこれを達成できますか?
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フォームを使用し、シェルフォームの場合のように直接シェルを実行する場合、環境変数の展開を行うのはドッカーではなくシェルです。
もう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コンテナーを誤って起動することはありません。
Dockerコンテナーでこれを行う一般的な方法は、環境変数を渡すことです。
docker run -p 9000:9000 -e NODE_ENV=dev -e CLUSTER=0 -d me/app