docker volumeの内容がビルド時と実行時で違うとき…

1 min読了の目安(約1300字TECH技術記事

しょーもないことですが1日溶かしたので共有

TL;DR

$ docker-compose down --volumes

前提

node_modulesをvolumeに結びつけてホストと同期しないように設定

docker-compose.yml
version: '3'

services:
  node:
    build: ./app
    volumes:
      - ./app:/app
      - node_modules:/app/node_modules
      
volumes:
  node_modules:
dockerfile
FROM node:14-alpine

WORKDIR /app
COPY ["package.json", "yarn.lock", "./"]

RUN yarn install --silent --production=false

CMD yarn start

ビルドして起動してみても、devDependenciesに入れたモジュールが走らずにコンテナが落ちてしまう…

調査

どうしても設定が違うようには思えない、というか、設定ファイルは過去のプロジェクトからの秘伝のタレなので動かないはずがない
わからなかったのでnode_modulesを比べてみた

FROM node:14-alpine

WORKDIR /app
COPY ["package.json", "yarn.lock", "./"]

RUN yarn install --silent --production=false

RUN ls -l node_modules

CMD ls -l node_modules

RUNの方にはdevDependenciesが含まれてるのにCMDの方には含まれてない!!

考察

  • volumeはコンテナとは独立していて、その内容は永続的

  • おそらく、コンテナとvolumeが結びつくのは ビルドからコンテナ実行までの間 で、
    RUNのとき参照してるのはコンテナの中のデータ
    CMDのとき参照してるのはvolumeの中のデータ
    なのだろう…

結論

正常なコンテナ内のデータが異常なvolume内のデータに上書きされているらしい

node_modulesが結びついているvolumeを消して、該当のimageをビルドし直す

$ docker-compose down --volumes
$ docker-compose up --build

もし消えなければ

$ docker volume ls
DRIVER              VOLUME NAME
local               node_modules
$ docker volume rm node_modules
$ docker-compose up --build