1. ホーム
  2. docker

[解決済み] Dockerコンテナ内にnode_modulesをインストールし、ホストと同期させる。

2023-04-03 04:37:16

質問

私は node_modules をDockerコンテナ内にインストールし、ホストと同期させるという問題があります。私のDockerのバージョンは 18.03.1-ce, build 9ee9f40 で、Docker Composeのバージョンは 1.21.2, build a133471 .

私の docker-compose.yml のように見えます。

# Frontend Container.
frontend:
  build: ./app/frontend
  volumes:
    - ./app/frontend:/usr/src/app
    - frontend-node-modules:/usr/src/app/node_modules
  ports:
    - 3000:3000
  environment:
    NODE_ENV: ${ENV}
  command: npm start

# Define all the external volumes.
volumes:
  frontend-node-modules: ~

私の Dockerfile :

# Set the base image.
FROM node:10

# Create and define the working directory.
RUN mkdir /usr/src/app
WORKDIR /usr/src/app

# Install the application's dependencies.
COPY package.json ./
COPY package-lock.json ./
RUN npm install

外部ボリュームを使ったトリックは、多くのブログ記事やStack Overflowの回答で説明されています。たとえば これ .

アプリケーションの動作は良好です。ソースコードは同期されています。ホットリローディングもうまくいっています。

唯一の問題は node_modules フォルダーがホスト上で空であることです。を同期させることは可能でしょうか? node_modules フォルダをホストと同期させることは可能でしょうか?

これらの回答はすでに読んでいます。

  1. node_modulesにdocker-composeのボリュームがあるが、空である。
  2. Docker内部でnpm installした後にnode_modulesにアクセスする。

残念なことに、これらはあまり役に立ちませんでした。私は 最初の を実行したくないからです。 npm install を実行したくないからです (例: ホストが Windows または Mac で、Docker コンテナが Debian 8 または Ubuntu 16.04 である場合)。 2つ目の を実行したいので、これも私にとっては良いことではありません。 npm install を私の Dockerfile をDockerコンテナの起動後に実行するのではなく

また このブログ記事 . 著者は、私が直面しているのと同じ問題を解決しようとしています。その問題とは node_modules をDockerコンテナからホストにコピーしているだけなので、同期されないということです。

私は自分の node_modules をホストと同期させたいのです。したいのですが、考慮してください。

  • をインストールする。 node_modules を自動的にインストールします。
  • をインストールする node_modules をホストではなくDockerコンテナ内にインストールします。
  • を持つように node_modules がホストと同期していること(Dockerコンテナ内に何か新しいパッケージをインストールした場合、手動で操作しなくても自動的にホストと同期していること)。

私は以下のものが必要です。 node_modules をホスト上に置く必要があるからです。

  • 必要なときにソース コードを読むことができる
  • IDE が必要とする node_modules にアクセスできるようにローカルにインストールする必要があります。 devDependencies のような eslint または prettier . 私はこれらをインストールしたくないのですが devDependencies をグローバルにインストールします。

よろしくお願いします。

どのように解決するのですか?

まず最初に、私は デビッド・メイズ トラスト512 に回答を投稿していただきました。残念ながら、彼らは私の問題を解決するために私を助けることはありませんでした。

この質問に対する私の答えを投稿したいと思います。

私の docker-compose.yml :

---
# Define Docker Compose version.
version: "3"

# Define all the containers.
services:
  # Frontend Container.
  frontend:
    build: ./app/frontend
    volumes:
      - ./app/frontend:/usr/src/app
    ports:
     - 3000:3000
    environment:
      NODE_ENV: development
    command: /usr/src/app/entrypoint.sh

私の Dockerfile :

# Set the base image.
FROM node:10

# Create and define the node_modules's cache directory.
RUN mkdir /usr/src/cache
WORKDIR /usr/src/cache

# Install the application's dependencies into the node_modules's cache directory.
COPY package.json ./
COPY package-lock.json ./
RUN npm install

# Create and define the application's working directory.
RUN mkdir /usr/src/app
WORKDIR /usr/src/app

そして、最後になりますが entrypoint.sh :

#!/bin/bash

cp -r /usr/src/cache/node_modules/. /usr/src/app/node_modules/
exec npm start

ここで一番やっかいなのは node_modulesnode_module のキャッシュディレクトリ ( /usr/src/cache ) で定義されている Dockerfile . その後に entrypoint.sh を移動します。 node_modules をキャッシュディレクトリ ( /usr/src/cache ) からアプリケーションディレクトリ ( /usr/src/app ). このおかげで、全体の node_modules ディレクトリがホストマシンに表示されます。

上記の私の質問を見て、私は望んでいた。

  • をインストールする node_modules を自動的にインストールします。
  • をインストールする node_modules をホストではなくDockerコンテナ内にインストールします。
  • を持つように node_modules がホストと同期していること(Dockerコンテナ内に何か新しいパッケージをインストールした場合、手動で操作することなく自動的に 手動で操作することなく、自動的にホストと同期されます。

が行われます。 node_modules は自動的にインストールされます。2つ目も行われます。 node_modules はDockerコンテナ内にインストールされます(したがって、クロスプラットフォームの問題は発生しません)。そして、3つ目もできています。 node_modules のように、Dockerコンテナ内にインストールされていたものが で表示されます。 になり、ホストマシン上では 同期される ! Dockerコンテナ内に新しいパッケージをインストールすると、ホストマシンとの同期が一度に行われます。

注意すべき点は、Dockerコンテナ内にインストールされた新しいパッケージは、本当の意味で /usr/src/app/node_modules . このディレクトリはホストマシンと同期しているため、この新しいパッケージはホストマシンの node_modules ディレクトリにも表示されます。しかし /usr/src/cache/node_modules には、この時点では古いビルドがあります (この新しいパッケージはありません)。いずれにせよ、これは私たちにとって問題ではありません。次の docker-compose up --build ( --build が必要)Dockerは再インストールして node_modules (なぜなら package.json が変更されたため)そして entrypoint.sh ファイルはそれらを私たちの /usr/src/app/node_modules .

もう一つ重要なことを考慮に入れておく必要があります。もしあなたが git pull がリモートリポジトリからのコードか git checkout your-teammate-branch に新しいパッケージが追加されることがあります。 package.json ファイルに新しいパッケージが追加されることがあります。この場合、Dockerを停止する際に CTRL + C で停止し、再度 docker-compose up --build ( --build は必須)。コンテナがデーモンとして動作している場合は、単に docker-compose stop を実行してコンテナを停止し、再度 docker-compose up --build ( --build は必須)。

何か質問があれば、コメントで教えてください。

お役に立てれば幸いです。