在 Docker 容器内安装 node_modules 并与主机同步 [英] Install node_modules inside Docker container and synchronize them with host
问题描述
我在 Docker 容器内安装 node_modules
并将它们与主机同步时遇到问题.我的Docker版本是18.03.1-ce,build 9ee9f40
,Docker Compose的版本是 1.21.2,build 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:
不幸的是,他们并没有给我太多帮助.我不喜欢 第一个,因为我不想运行 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
或prettier代码>.我不想全局安装这些
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 thedevDependencies
such aseslint
orprettier
. I don't want to install thesedevDependencies
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 容器内(因此,不会有跨平台问题).第三件事也完成了:安装在 Docker 容器内的 node_modules
将在我们的主机上可见,并且它们将同步!如果我们在 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
.
您应该考虑一件更重要的事情.如果在Docker运行时git pull
远程仓库中的代码或者git checkout your-teammate-branch
,可能会有一些新的包添加到包中.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屋!