docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > Docker node热加载

使用Docker进行node开发时实现热加载功能

作者:冷夜星光

这篇文章主要介绍了使用docker进行vue、react或者node开发时实现热加载功能,即宿主机文件修改之后实时刷新或者实时重启服务,文中通过代码示例介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下

说明:使用docker进行vue、react或者node开发时实现热加载功能,即宿主机文件修改之后实时刷新或者实时重启服务。

不使用docker

本地开发node程序的时候只需要配置 nodemon 启动就可以了,例如
假设你有一个简单的 Node.js 文件,名为 app.js,内容如下:

const http = require('http');

const server = http.createServer((req, res) => {
    res.writeHead(200, {'Content - Type': 'text/plain'});
    res.end('Hello, World!\n');
});

server.listen(3000, () => {
    console.log('Server running on port 3000');
});

然后只需要运行以下命令

npm install -g nodemon
nodemon app.js

此时,当你修改 app.js 文件内容之后,nodemon 就会检测到文件变化并自动重启服务器,刷新页面之后你就能立即看到修改后的效果。

使用docker

docker版本为 Docker version 27.1.1, build 6312585 ,且已经配置好 dockerfile 文件的基础之上。实现本地文件与容器内文件的同步有多种方法。在这儿只介绍在compose.yaml配置的两种方法,分别是:

1. 使用 watch 同步配置(推荐):

services:
  server:
    build:
      context: .
    ports:
      - 3000:3000
    develop:
      watch:
        - path: ./package.json  # 监听当前目录下的package.json文件
          action: rebuild  # package.json文件变化时docker会重新构建,与docker compose up --build等效
        - path: .   # 监听当前目录
          target: /usr/src/app  # 容器中的目标路径,将宿主机的当前目录与容器内的/usr/src/app路径相关联
          ignore:   # 忽视的文件
            - node_modules/
          action: sync # 同步动作,docker会确保对主机上文件所做的任何更改自动与服务容器内的相应文件相匹配。
    command: nodemon app.js

请仔细看注释,此时只需要运行 docker compose up --watch 命令即可实现热更新。 更多配置请前往官方文档查看

2. 使用Bind Mounts绑定挂载(容器文件更改会同步到宿主机):

services:
  server:
    build:
      context: .
    ports:
      - 3000:3000
    volumes:
      - .:/usr/src/app  # 绑定挂载宿主机当前目录到容器
      - /usr/src/app/node_modules   # 创建一个匿名卷用于存储容器的node_modules,防止本地 node_modules目录覆盖容器中的依赖。
    command: nodemon --legacy-watch --polling-interval 1000 app.js  # 此处命令与上面不一致

请仔细看注释,使用该配置运行 docker compose up 命令也能实现热更新。

注意:

相信你也注意到了command命令和上面的 不一致,这是因为直接运行 nodemon app.js 在windows下会出现热加载失效的情况。具体现象是在容器内修改文件时,nodemon 能够正确检测到更改并热加载应用;但在宿主机修改文件时,尽管文件已经同步到容器内,nodemon 却未能检测到这些更改,从而无法触发热加载。

原因: 在 Docker 环境中,尤其是在 macOS 和 Windows 上,由于底层文件系统的差异,文件系统事件(如 inotify 事件)可能无法正确地从宿主机传递到容器。这导致 nodemon 无法检测到宿主机上的文件更改。因此,尽管文件已同步到容器内,nodemon 依然未能触发热加载。

解决方案: 配置 nodemon 使用轮询,也就是 nodemon --legacy-watch --polling-interval 1000 app.js 命令实现热加载功能。不过需要注意的是相较于默认模式,轮询模式会消耗更多的 CPU 和 I/O 资源,尤其是在大规模项目或频繁文件变更的时候。另外也可以尝试使用 docker-syncmutagen 等工具来解决这个问题,不过我没试过。

总结

1.使用 watch 同步配置

优点

缺点

适用场景

2.使用Bind Mounts绑定挂载

优点

缺点

适用场景

以上就是使用Docker进行node开发时实现热加载功能的详细内容,更多关于Docker node热加载的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文