在Docker容器中安装node_modules并将其与主机同步 [英] Install node_modules inside Docker container and synchronize them with host

查看:128
本文介绍了在Docker容器中安装node_modules并将其与主机同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Docker容器中安装 node_modules 并将它们与主机同步时遇到问题。我的Docker版本为 18.03.1-ce,内部版本9ee9f40 ,而Docker Compose的版本为 1.21.2,内部版本a133471

I have the problem with installing node_modules inside the Docker container and synchronize them with the host. My Docker's version is 18.03.1-ce, build 9ee9f40 and Docker Compose's version is 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答案中都介绍了与外部卷有关的技巧。例如,这个

The trick with the external volume is described in a lot of blog posts and Stack Overflow answers. For example, this one.

该应用程序运行良好。源代码已同步。

The application works great. The source code is synchronized. The hot reloading works great too.

我唯一的问题是主机上的 node_modules 文件夹为空。可以将Docker容器内的 node_modules 文件夹与主机同步吗?

The only problem that I have is that node_modules folder is empty on the host. Is it possible to synchronize the node_modules folder that is inside Docker container with the host?

我已经阅读过这些答案:

I've already read these answers:


  1. docker组成node_modules上的卷,但为空

  2. npm安装在Docker内部后访问node_modules

  1. docker-compose volume on node_modules but is empty
  2. Accessing node_modules after npm install inside Docker

不幸的是,他们对我没有太大帮助。我不喜欢第一个,因为我不想运行 npm install 在我的主机上,因为可能存在跨平台问题(例如,主机是Windows或Mac,而Docker容器是Debian 8或Ubuntu 16.04)。 第二个对我也不利,因为我想运行 npm install 在我的 Dockerfile 中,而不是在Docker容器启动后运行它。

Unfortunately, they didn't help me a lot. I don't like the first one, because I don't want to run npm install on my host because of the possible cross-platform issues (e.g. the host is Windows or Mac and the Docker container is Debian 8 or Ubuntu 16.04). The second one is not good for me too, because I'd like to run npm install in my Dockerfile instead of running it after the Docker container is started.

此外,我发现了此博客文章。作者试图解决我面临的同样问题。问题是 node_modules 不会同步,因为我们只是将它们从Docker容器复制到主机。

Also, I've found this blog post. The author tries to solve the same problem I am faced with. The problem is that node_modules won't be synchronized because we're just copying them from the Docker container to the host.

我希望将Docker容器内的 node_modules 与主机同步。请考虑以下因素:

I'd like my node_modules inside the Docker container to be synchronized with the host. Please, take into account that I want:


  • 自动安装 node_modules 手动

  • node_modules 安装在Docker容器而不是主机中

  • 具有 node_modules 与主机同步(如果我在Docker容器中安装了一些新软件包,则应自动与主机同步,而无需任何手动操作)

  • to install node_modules automatically instead of manually
  • to install node_modules inside the Docker container instead of the host
  • to have node_modules synchronized with the host (if I install some new package inside the Docker container, it should be synchronized with the host automatically without any manual actions)

我需要在主机上安装 node_modules ,因为:

I need to have node_modules on the host, because:


  • 在需要时可以读取源代码

  • IDE需要 node_modules 在本地安装,以便可以访问 devDependencies ,例如 eslint 更漂亮。我不想在全球安装这些 devDependencies

  • possibility to read the source code when I need
  • the IDE needs node_modules to be installed locally so that it could have access to the devDependencies such as eslint or prettier. I don't want to install these devDependencies globally.

预先感谢。

推荐答案

首先,我要感谢 David Maze trust512 来发布他们的答案。不幸的是,他们没有帮助我解决我的问题。

At first, I would like to thank David Maze and trust512 for posting their answers. Unfortunately, they didn't help me to solve my problem.

我想发布我对这个问题的答案。

I would like to post my answer to this question.

我的 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

And last but not least entrypoint.sh:

#!/bin/bash

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

这里最棘手的部分是将 node_modules 安装到 node_module 的缓存目录( / usr / src / cache )在我们的 Dockerfile 中定义。之后, entrypoint.sh 将从缓存目录中移动 node_modules / usr / src / cache )到我们的应用程序目录( / usr / src / app )。因此,整个 node_modules 目录将出现在我们的主机上。

The trickiest part here is to install the node_modules into the node_module's cache directory (/usr/src/cache) which is defined in our Dockerfile. After that, entrypoint.sh will move the node_modules from the cache directory (/usr/src/cache) to our application directory (/usr/src/app). Thanks to this the entire node_modules directory will appear on our host machine.

看着上面的问题,我想要:

Looking at my question above I wanted:



  • 来自动安装 node_modules

  • node_modules 安装在Docker容器而不是主机中

  • 具有 node_modules 与主机同步(如果我在Docker容器中安装了一些新软件包,则应该
    自动与主机同步,无需任何手动操作

  • to install node_modules automatically instead of manually
  • to install node_modules inside the Docker container instead of the host
  • to have node_modules synchronized with the host (if I install some new package inside the Docker container, it should be synchronized with the host automatically without any manual actions

第一件事已经完成: node_modules 是自动安装的。事情也完成了: node_modules 安装在Docker容器内(因此,不会出现跨平台问题),第三件事也完成了:<$ c $安装在Docker容器中的c> node_modules 将是 vi sible 在我们的主机上,它们将被同步!如果我们在Docker容器中安装了一些新软件包,它将立即与我们的主机同步。

The first thing is done: node_modules are installed automatically. The second thing is done too: node_modules are installed inside the Docker container (so, there will be no cross-platform issues). And the third thing is done too: node_modules that were installed inside the Docker container will be visible on our host machine and they will be synchronized! If we install some new package inside the Docker container, it will be synchronized with our host machine at once.

需要注意的重要一点:确实,新软件包已安装在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

The important thing to note: truly speaking, the new package installed inside the Docker container, will appear in /usr/src/app/node_modules. As this directory is synchronized with our host machine, this new package will appear on our host machine's node_modules directory too. But the /usr/src/cache/node_modules will have the old build at this point (without this new package). Anyway, it is not a problem for us. During next docker-compose up --build (--build is required) the Docker will re-install the node_modules (because package.json was changed) and the entrypoint.sh file will move them to our /usr/src/app/node_modules.

您应考虑到更重要的一件事如果您从远程存储库中 git pull 中的代码或 git在Docker运行时签出您的teammate-branch ,可能是一些添加到 package.json 文件中的新软件包。在这种情况下,您应该使用 CTRL + C 停止Docker,然后使用 docker-compose up --build (需要-build )。如果您的容器作为守护程序运行,则只需执行 docker-compose stop 来停止容器,然后使用 docker-compose up再次启动- -build (需要-build )。

You should take into account one more important thing. If you git pull the code from the remote repository or git checkout your-teammate-branch when Docker is running, there may be some new packages added to the package.json file. In this case, you should stop the Docker with CTRL + C and up it again with docker-compose up --build (--build is required). If your containers are running as a daemon, you should just execute docker-compose stop to stop the containers and up it again with docker-compose up --build (--build is required).

如果有任何疑问,请在评论中让我知道。

If you have any questions, please let me know in the comments.

希望这会有所帮助。

这篇关于在Docker容器中安装node_modules并将其与主机同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆