docker-composeで環境によってDockerfileのCMDを使い分けたい
やりたいこと
少し複雑なdocker-composeでテスト向けと、その他の環境(developmentやproduction)の設定を使い分けたいです。
その時、docker-compose
のコマンドを呼び出す時のオプションで使い分けられるようにしたいです。
ここで、docker-compose
の-f
オプションで、docker-compose
の値を変えることができるのは知っていたのですが、ここでしたいのは、Dockerfile
に書かれてある
CMD ["npm", "test"]
を、実行時には
CMD ["node", "index.js"]
としたいということです。最初はif文で書いても良いのかと思いましたが、後の章で書いていますが、あまり良くないようです。
環境
本来はもっと複雑なのですが、記事用に簡素化します。使っているものは以下の3つだけです。
- node.js
- mariadb
- docker-engine & docker-compose
環境による分け方
色々と調べた結果、daisuke furukawaさんの記事[1]のように、環境によってDockerfileを分け、docker-compose.yml
とは別に、例えば、development.yml
のようなdocker-composeのdeploy環境情報を上書きするファイルを作りdeployするのが良さそうです。個人的には、ファイルの数が多くなって、あまり気が進まないのですが…
例えば
- Dockerfile: テスト用
- Dockerfile.dev: ローカル実行用
- docker-compose.yml: テスト用をベースとしたdocker-compose
- development.yml: ローカル実行用にdocker-composeを上書きする
と言った感じですね。
そして、テストをするときは、普通に
docker-compose up --build
と実行して、ローカルで実際に動かすときは
docker-compose -f docker-compose.yml -f development.yml up --build
と言った感じに動かします。
ちなみに、development.yml
は
version: "3"
services:
api:
build:
dockerfile: ./Dockerfile.dev
web:
build:
dockerfile: ./Dockerfile.dev
というように、変更点だけ書けばOKです。
良くない(であろう)例は次の章に書いています。
良くない(であろう)例〜Dockerfileにif文を書く〜
僕もはじめ、推測では、node.jsで立てるコンテナのDockerfileで実行するコマンドを、環境によって使い分けることをしないといけないと思っていました。
例えば、こんな感じ
FROM node:16
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
RUN npm install pm2 -g
COPY . .
EXPOSE 3000
if NODE_ENV == "TEST"
CMD ["npm", "test"]
else
CMD ["pm2-runtime" ,"web.config.js"]
しかし、@t_nさんの記事[2]によるとif文を使う方法は、あまり良くないようです。
さいごに
自分は職業エンジニアではなく、実務で使ったことがないので、もっといい方法があれば、ご教示いただけると幸いです。
-
dockerで本番環境と開発環境を使い分ける方法いろいろ / daisuke furukawa https://crieit.net/posts/docker (2022-04-15閲覧) ↩︎
-
DockerFileにif文(条件分岐) / @t_n (Qiita) https://qiita.com/t_n/items/203cd3593427a35f7ed7 (2022-04-15閲覧) ↩︎
Discussion