夢のかけら

Goエンジニアの技術ブログ

【Docker】docker-composeのvolumesではホストのファイルがコンテナのファイルを上書きする

DockerfileのRUNとCMD、docker-compose.yaml内のマウントタイミング - Qiitaより引用

docker-compose.yamlでマウントしたファイルに対して、Dockerfileで操作したいときは RUNではなくCMDを使う。

順番は、RUN→volumes→CMDだ。

この順番を忘れて定期的にハマっている。 具体的にはDockerfile内でライブラリをインストールしたはずなのに、ライブラリが見つからない、というパターン。

# NG

FROM node:16-alpine

WORKDIR /usr/src/app

COPY package*.json /usr/src/app/
RUN npm i

COPY . /usr/src/app

EXPOSE 3000
CMD  "npm" "run" "dev"
 volumes:
      - ./:/usr/src/app

このように書いた場合、マウント時にホストのnode_modulesがコンテナのnode_moudulesを上書きしてしまう。volumesにおけるマウントはホストのファイルシステムが優先される。 つまり、せっかくのRUN npm iが無駄になってしまう。なぜなら実行される順番は RUNvolumesCMDだから。解決策としてはCMDnpm iを持ってくる。

# OK
FROM node:16-alpine

WORKDIR /usr/src/app

COPY package*.json /usr/src/app/
COPY . /usr/src/app

EXPOSE 3000
CMD "sh" "-c" "npm install && npm run dev"

↑のように書けば、volumesでファイルシステムが同期された後にnpm iでコンテナにnode_moudulesができて、それがホストにやってくる。 Dockerにおける開発環境構築では最後にCMDで ライブラリーのインストール && サーバー起動というのが1つの鉄板パターンなのかもしれない。