docker容器内的Nodemon
Posted
技术标签:
【中文标题】docker容器内的Nodemon【英文标题】:Nodemon inside docker container 【发布时间】:2018-06-27 19:10:00 【问题描述】:我正在尝试在 docker 容器中使用 nodemon:
Dockerfile
FROM node:carbon
RUN npm install -g nodemon
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "nodemon" ]
构建/运行命令
docker build -t tag/apt .
docker run -p 49160:8080 -v /local/path/to/apt:/usr/src/app -d tag/apt
将本地卷附加到容器以监视代码更改,导致一些覆盖和 nodemon 抱怨找不到节点模块(其中任何一个)。我该如何解决这个问题?
【问题讨论】:
通过输入容器确保所有文件都正确存在于 /usr/src/app 中:docker exec -ti <container name> sh
在我写的时候,如果我将本地卷附加到容器,node_modules 文件夹就会丢失。如果没有附加的卷,模块会存在,但我无法“监听”主机代码的变化。
好的,我知道了,我会写一个答案
【参考方案1】:
在您Dockerfile
中,您在复制您的package*json
文件后正在运行npm install
。 node_modules
目录在 /usr/src/app
中正确创建,您可以开始了。
但是,当您在 /usr/src/app
上挂载本地目录时,容器内该目录的内容会被您本地版本的节点项目覆盖,显然缺少 node_modules
目录,从而导致您遇到的错误体验。
挂载目录后,您需要在正在运行的容器上运行npm install
。例如,您可以运行类似:
docker exec -ti <containername> npm install
请注意,您必须暂时将您的 CMD
指令更改为:
CMD ["sleep", "3600"]
为了能够进入容器。
这将导致在您的本地目录中创建一个 node_modules 目录,并且您的容器应该正确运行 nodemon(在切换回您当前的 CMD
之后)。
【讨论】:
Holy xyeet,多年来一直在寻找解决方案,这清楚地解释了为什么会出现问题,而且解决方案也很简单! :)【参考方案2】:TL;DR:npm install
在子文件夹中,同时将 node_modules
文件夹移动到根目录。
试试这个配置看看,它应该对你有帮助。
FROM node:carbon
RUN npm install -g nodemon
WORKDIR /usr/src/app
COPY package*.json /usr/src/app/
RUN npm install && mv /usr/src/app/node_modules /node_modules
COPY . /usr/src/app
EXPOSE 8080
CMD [ "nodemon" ]
正如另一个答案所说,即使您在 WORKDIR
上运行了 npm install
。当您挂载该卷时,WORKDIR
的内容会临时替换为您的挂载文件夹,npm install
没有运行。
当节点搜索其require package in serveral location 时,一种解决方法是将“已安装”的node_modules
文件夹移动到根目录,这是它的必需路径之一。
这样做你仍然可以更新代码,直到你需要一个新的包,图像需要另一个build
。
我从 docker sample project 引用了 Dockerfile。
【讨论】:
【参考方案3】:在 javascript 或 Nodejs 应用程序中,当我们使用 Docker 容器中的绑定卷绑定 src 文件时,无论是使用 docker 命令还是 docker-compose,我们最终都会覆盖 node_modules 文件夹。要克服这个问题,您需要使用匿名卷。在匿名卷中,与我们指定source:destination
文件夹路径的绑定卷相比,我们仅提供目标文件夹路径。
一般语法
--volume <container file system directory absolute path>:<read write access>
一个示例 docker run 命令
docker container run \
--rm \
--detach \
--publish 3000:3000 \
--name hello-dock-dev \
--volume $(pwd):/home/node/app \
--volume /home/node/app/node_modules \
hello-dock:dev
如需进一步参考,请查看 Farhan Hasin Chowdhury 的 handbook
【讨论】:
【参考方案4】:也许没有必要挂载整个项目。在这种情况下,我只会挂载放置所有源文件的目录,例如src/
.
这样node_modules/
目录不会有任何问题。
另外,如果您使用的是 Windows,您可能需要在 nodemon 命令中添加 -L(--legacy-watch)选项,正如您在 issue 中看到的那样。所以应该是nodemon -L
。
【讨论】:
以上是关于docker容器内的Nodemon的主要内容,如果未能解决你的问题,请参考以下文章