Vla*_*rak 34 npm node-modules docker docker-compose
我有在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: ~
Run Code Online (Sandbox Code Playgroud)
我的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
Run Code Online (Sandbox Code Playgroud)
许多博客文章和Stack Overflow答案都描述了外部卷的技巧.例如,这一个.
该应用程序运行良好.源代码是同步的.热重装也很有效.
我唯一的问题是该node_modules
文件夹在主机上是空的.是否可以将node_modules
Docker容器内的文件夹与主机同步?
我已经读过这些答案:
不幸的是,他们并没有帮助我很多.我不喜欢第一个,因为我不想npm install
在我的主机上运行,因为可能存在跨平台问题(例如主机是Windows或Mac,Docker容器是Debian 8或Ubuntu 16.04).第二个是对我不好过,因为我想运行npm install
在我Dockerfile
,而不是泊坞容器运行后它已启动.
另外,我发现了这篇博文.作者试图解决我面临的同样问题.问题是node_modules
不会同步,因为我们只是将它们从Docker容器复制到主机.
我希望我node_modules
的Docker容器内部与主机同步.请考虑我想要:
node_modules
自动安装而不是手动安装node_modules
在Docker容器内而不是主机中node_modules
与主机同步(如果我安装多克尔容器内的一些新的包装,应自动与主机,而无需任何手动操作同步)我需要node_modules
在主机上,因为:
node_modules
在本地安装,以便它可以访问devDependencies
诸如eslint
或prettier
.我不想devDependencies
全局安装这些.提前致谢.
Vla*_*rak 32
首先,我要感谢David Maze和trust512发布他们的答案.不幸的是,他们没有帮助我解决我的问题.
我想发表我对这个问题的回答.
我的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
Run Code Online (Sandbox Code Playgroud)
我的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
Run Code Online (Sandbox Code Playgroud)
最后但并非最不重要entrypoint.sh
:
#!/bin/bash
cp -r /usr/src/cache/node_modules/. /usr/src/app/node_modules/
exec npm start
Run Code Online (Sandbox Code Playgroud)
这里最棘手的部分是安装node_modules
到我们的定义node_module
的缓存目录(/usr/src/cache
)中Dockerfile
.之后,entrypoint.sh
将从node_modules
缓存目录(/usr/src/cache
)移动到我们的应用程序目录(/usr/src/app
).多亏了这一点,整个node_modules
目录将出现在我们的主机上.
看看我上面的问题,我想:
node_modules
自动安装而不是手动安装- 安装
node_modules
在Docker容器内而不是主机中- 已经
node_modules
与主机(同步,如果我安装多克尔容器内的一些新的包装,应自动与主机无需任何手动操作同步
第一件事就是完成:node_modules
自动安装.第二件事也是这样做的:node_modules
安装在Docker容器内(因此,不存在跨平台问题).第三件事也是这样做的: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
Docker运行时,可能会有一些新的软件包添加到该package.json
文件中.在这种情况下,您应该CTRL + C
使用docker-compose up --build
(--build
需要)停止Docker 并再次使用它.如果您的容器作为守护程序运行,您应该执行docker-compose stop
以停止容器并再次使用docker-compose up --build
(--build
需要).
如果您有任何疑问,请在评论中告诉我.
希望这可以帮助.
Jer*_*M4n 14
您可以使用外部命名卷技巧在容器中安装node_modules ,并通过将卷的存储位置配置为指向主机的node_modules目录来将其与主机同步。这可以通过使用本地驱动程序和绑定安装的命名卷来完成,如下面的示例所示。
卷的数据无论如何都存储在您的主机上,例如 /var/lib/docker/volumes/ 中,因此我们只是将其存储在您的项目中。
要在 Docker Compose 中执行此操作,只需将 node_modules 卷添加到前端服务,然后在命名卷部分中配置该卷,其中“device”是相对路径(来自 docker-compose.yml 的位置)您的本地(主机)node_modules 目录。
docker-compose.yml
version: '3.9'
services:
ui:
# Your service options...
volumes:
- node_modules:/path/to/node_modules
volumes:
node_modules:
driver: local
driver_opts:
type: none
o: bind
device: ./local/path/to/node_modules
Run Code Online (Sandbox Code Playgroud)
此解决方案的关键是永远不要直接在主机的 node_modules 中进行更改,而是始终在容器中安装、更新或删除 Node 包。
版本控制提示: 当您的 Node package.json/package-lock.json 文件发生更改时,无论是在拉取或切换分支时,除了重建 Image 之外,您还必须删除 Volume 并删除其内容:
docker volume rm example_node_modules
rm -rf local/path/to/node_modules
mkdir local/path/to/node_modules
Run Code Online (Sandbox Code Playgroud)
文档:
lew*_*lbr 11
遇到这个问题并发现接受的答案node_modules
在每个容器运行中将所有内容复制到主机的速度很慢,我设法通过在容器中安装依赖项、镜像主机卷并在存在node_modules
文件夹时再次跳过安装来解决它:
Dockerfile:
FROM node:12-alpine
WORKDIR /usr/src/app
CMD [ -d "node_modules" ] && npm run start || npm ci && npm run start
Run Code Online (Sandbox Code Playgroud)
docker-compose.yml:
version: '3.8'
services:
service-1:
build: ./
volumes:
- ./:/usr/src/app
Run Code Online (Sandbox Code Playgroud)
当您需要重新安装依赖项时,只需删除node_modules
.
小智 6
没有人提到实际使用 dockerentrypoint
功能的解决方案。
这是我的工作解决方案:
Dockerfile(多阶段构建,因此它既可用于生产又可用于本地开发):
FROM node:10.15.3 as production
WORKDIR /app
COPY package*.json ./
RUN npm install && npm install --only=dev
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
FROM production as dev
COPY docker/dev-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["dev-entrypoint.sh"]
CMD ["npm", "run", "watch"]
Run Code Online (Sandbox Code Playgroud)
码头工人/开发入口点.sh:
#!/bin/sh
set -e
npm install && npm install --only=dev ## Note this line, rest is copy+paste from original entrypoint
if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ]; then
set -- node "$@"
fi
exec "$@"
Run Code Online (Sandbox Code Playgroud)
docker-compose.yml:
version: "3.7"
services:
web:
build:
target: dev
context: .
volumes:
- .:/app:delegated
ports:
- "3000:3000"
restart: always
environment:
NODE_ENV: dev
Run Code Online (Sandbox Code Playgroud)
通过这种方法,您可以实现所需的所有 3 点,恕我直言,这是一种更简洁的方法 - 无需四处移动文件。
这里发生了三件事:
docker build
或时docker-compose build
,您的Dockerfile将构建一个新映像,其中包含/usr/src/app/node_modules
目录和Node安装,但仅此而已。特别是,您的应用程序不在生成的映像中。docker-compose up
,该volumes: ['./app/frontend:/usr/src/app']
指令将隐藏其中的任何/usr/src/app
内容,并将主机系统内容装载到该指令之上。volumes: ['frontend-node-modules:/usr/src/app/node_modules']
指令将命名卷安装在node_modules
树的顶部,隐藏相应的主机系统目录。如果您要启动另一个容器并将其附加到其上,那么我希望您会在其中看到node_modules
树。对于您要描述的内容,您只是不需要指定的卷:从代码volumes:
块和文件volumes:
末尾的部分删除第二行docker-compose.yml
。
归档时间: |
|
查看次数: |
17808 次 |
最近记录: |