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 installnode_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;DRnpm 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的主要内容,如果未能解决你的问题,请参考以下文章

无法连接到 Docker 容器内的 MongoDB

udevadm 不显示 docker 容器内的所有属性

Docker 修改容器内的时区

使用映射端口访问 docker 容器内的 JMX

Docker容器内的权限被拒绝

Docker - 无法通过脚本删除容器内的文件