使用Docker进行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-sync
或 mutagen
等工具来解决这个问题,不过我没试过。
总结
1.使用 watch
同步配置
优点:
- 高级同步策略:可以针对特定文件或目录设置不同的同步策略,例如仅在某些文件更改时触发重建。
- 自动化流程:结合自动重建和同步,提升开发效率,减少手动操作。
- 灵活性:可以根据项目需求定制同步和重建的行为,适应复杂的开发流程。
缺点:
- 维护成本:配置可能需要更多的维护,尤其是在团队协作或项目规模扩大时。
适用场景:
- 大多数项目:适用于大多数项目,个人强烈推荐。
2.使用Bind Mounts绑定挂载
优点:
- 实时同步:任何在宿主机上更改会立即在容器内生效,反之亦然。
- 简单直观:配置简单,直接映射宿主机目录到容器目录。
缺点:
- 性能问题:在某些操作系统(如 macOS 和 Windows)上,绑定挂载的性能可能较差,尤其是在大量文件操作时。另外在windows下文件系统事件可能无法及时传递。
- 路径依赖:绑定挂载路径依赖于宿主机的文件系统结构,可能影响跨平台的可移植性。
- 权限管理:需要确保宿主机和容器内的文件权限一致,避免权限冲突问题。
适用场景:
- 开发环境:需要频繁修改代码并希望这些更改即时反映到运行中的容器中。
- 简单项目:项目结构简单,不需要复杂的文件同步策略。
以上就是使用Docker进行node开发时实现热加载功能的详细内容,更多关于Docker node热加载的资料请关注脚本之家其它相关文章!