Docker容器内使用Nodemon

14

我正在尝试在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 <容器名称> sh - whites11
正如我所写的,如果我将本地卷附加到容器上,则会丢失node_modules文件夹。如果没有附加的卷,则模块存在,但我无法“监听”主机机器代码的更改。 - Jumpa
好的,我明白了,我会写一个答案。 - whites11
4个回答

12

在你的Dockerfile中,你在复制package*json文件之后运行了npm install。一个 node_modules 目录会被正确地创建在 /usr/src/app 中,然后你就可以使用了。

然而,当你将本地目录挂载到 /usr/src/app 时,容器内此目录的内容会被你本地的 node 项目覆盖,这导致了你所遇到的错误,因为它缺少了 node_modules 目录。

在挂载目录后,你需要在运行的容器中运行 npm install。例如,你可以运行以下命令:

docker exec -ti <containername> npm install
请注意,您将需要暂时更改您的CMD指令,例如:
CMD ["sleep", "3600"]

为了能够进入容器。

这将会在你的本地目录中创建一个 node_modules 目录,并且在切换回你当前的 CMD 后,你的容器应该可以正确地运行 nodemon。


哇塞,我已经寻找解决方案好久了,这个解释非常清晰,为什么问题会发生以及如此简单的解决方案! :) - ruohola

7

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没有运行。
由于node在几个位置搜索其要求包,一个解决方法是将“已安装”的node_modules文件夹移动到根目录,这是其要求路径之一。
这样做可以更新代码,直到您需要一个新的包,该镜像需要另一个build
我参考了这个docker示例项目中的Dockerfile。

2

在Javascript或Nodejs应用程序中,当我们使用Docker容器中的绑定卷(使用docker命令或docker-compose)绑定src文件时,会覆盖node_modules文件夹。为了解决这个问题,您需要使用匿名卷。在匿名卷中,我们只提供目标文件夹路径,而在绑定卷中,我们指定源:目标文件夹路径。

一般语法

--volume <container file system directory absolute path>:<read write access>

一个Docker运行命令的例子。
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的《Docker手册》


0

也许没有必要挂载整个项目。在这种情况下,我只会挂载放置所有源文件的目录,例如 src/

这样你就不会遇到 node_modules/ 目录的任何问题。

此外,如果你使用的是 Windows 操作系统,你可能需要在 nodemon 命令中添加 -L (--legacy-watch) 选项,就像你可以在这个 issue 中看到的那样。所以命令应该是 nodemon -L


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接