docker build で npm install してたら時間がかかって辛かった話

Node.js の Web アプリケーションを Docker コンテナにする場合、以下のようにして RUNnpm install を実行するのが一般的だと思います。

Dockerfile

(省略)
RUN npm install
(省略)

これにより docker build 時に npm install が呼ばれます。

基本的にはこれで問題ないのですが、 CI で頻繁に docker build を実行する場合に、毎回 npm install を実行すると時間がかかってしまいます。 通常の node アプリケーションでは、 CI で node_modules をキャッシュするものだと思いますが、さすがにコンテナ内の node_modules は CI ではキャッシュできません。

悩んだ結果、以下のようにして npm install を CI で行い、 Dockerfile でそれを COPY するようにしました。

circle.yml

(省略)
dependencies:
  override:
    - npm install
(省略)

Dockerfile

(省略)
COPY ./node_modules /app/
(省略)

これにより CI で時間がかかる問題は解消されました。

しかしこの方法では docker build の前に必ず npm install が必要になってしまうので、正しいやり方ではないようにも感じます。 もっと良いやり方があれば教えてほしい...。