
在 Docker(尤其是 Windows + WSL2)中运行 Bun 项目时,--watch 默认无法监听宿主机文件变更,导致热重载失效;正确解法是启用 Bun 原生 --hot 模式,并配合挂载优化与文件系统适配配置。
在 docker(尤其是 windows + wsl2)中运行 bun 项目时,`--watch` 默认无法监听宿主机文件变更,导致热重载失效;正确解法是启用 bun 原生 `--hot` 模式,并配合挂载优化与文件系统适配配置。
Bun 自 v1.3 起原生支持高性能热重载(Hot Module Replacement, HMR),其底层基于操作系统级文件监听 API(Linux inotify、macOS kqueue、Windows ReadDirectoryChangesW),响应速度比 JS 实现的 --watch 快 10 倍以上。但在 Docker 容器中,尤其当使用 WSL2 + Windows 文件系统(如 /mnt/c/...)时,inotify 事件常因虚拟文件系统层被丢弃或延迟,造成 bun --watch 完全失灵——这正是你遇到的核心问题:独立运行正常,Docker 中却“改了代码无反应”。
✅ 正确方案:用 --hot 替代 --watch
Bun 的 --hot 标志专为开发场景设计,它不仅启用快速文件监听,还自动注入 HMR 运行时逻辑、处理模块热替换、保留应用状态(如 React 组件状态),且对 Docker 友好性显著优于 --watch。请立即修改你的 api/package.json:
{
"scripts": {
"dev": "bun --hot run src/index.ts"
}
}
⚠️ 注意:bun --hot 不兼容 bun run 的多参数模式(如 bun --hot run src/index.ts --port=8000),若需传参,请改用 bun --hot src/index.ts 直接执行文件(Bun 会自动识别 TypeScript 并跳过编译步骤)。
同时更新 api/Dockerfile,确保入口命令与脚本一致:
# api/Dockerfile(关键修改) FROM oven/bun:1.3.0-slim # 强烈建议升级至 1.3.x(2025年10月发布,HMR 稳定性大幅提升) WORKDIR /app COPY package*.json bun.lockb ./ RUN bun install --production=false # 确保 devDependencies(如 bun-types)也被安装 COPY . . # 删除旧的 CMD,改用 npm script 启动(更可控) CMD ["npm", "run", "dev"]
? Docker 适配增强:解决 WSL2/inotify 限制
即使启用 --hot,WSL2 下仍可能因内核 inotify 限制触发失败。请在 docker-compose.yml 的 api 和 web 服务中添加以下配置:
# docker-compose.yml(新增部分)
services:
api:
# ... 其他配置保持不变
volumes:
- ./api/:/app:delegated # 关键:显式声明 delegated 模式,提升文件事件可靠性
# 新增 ulimit 和 sysctl 适配
ulimits:
inotify: 524288
sysctls:
fs.inotify.max_user_watches: 524288
fs.inotify.max_user_instances: 1024
? delegated 是 Docker for WSL2 推荐的挂载一致性模式,它允许容器异步接收文件变更通知,大幅降低 inotify 丢失率。避免使用 cached(可能延迟)或默认(行为不稳定)。
? Astro Web 侧同步修复(补充)
你的 web/ 项目使用 Astro,而 Astro v4.9+ 已原生支持 Bun 开发服务器(astro dev --host)。但 Docker 中需额外配置:
-
在 web/astro.config.mjs 中启用 host 模式:
export default defineConfig({ output: 'static', devToolbar: { enabled: true }, server: { host: true, // 允许外部访问(Nginx 代理必需) port: 3000, open: false, } }); -
修改 web/Dockerfile,使用 Bun 启动而非 Astro CLI(减少依赖层级):
FROM oven/bun:1.3.0-slim WORKDIR /app COPY package*.json bun.lockb ./ RUN bun install COPY . . # Astro 项目直接用 Bun 托管(Bun v1.3 内置静态服务 + HMR) CMD ["bun", "--hot", "run", "astro", "dev", "--host", "--port=3000"]
? 验证与调试技巧
-
检查 Bun 是否真正监听:启动后观察控制台输出,成功时应显示类似:
Bun v1.3.0 ready in 8.2 ms → http://localhost:8000/ Hot reloading enabled (inotify backend) Watching 127 files...
- 手动触发 inotify 测试:进入容器 docker exec -it cv_api sh,执行 touch src/index.ts,观察日志是否打印 File changed: src/index.ts — reloading...。
- 禁用 IDE 自动保存干扰:VS Code 中关闭 files.autoSave: "onFocusChange",改为 onDelay 或手动 Ctrl+S,避免临时文件(.swp/.tmp)触发误重启。
✅ 总结:三步落地热重载
| 步骤 | 操作 | 目的 |
|---|---|---|
| 1. 替换监听模式 | package.json 中 dev 脚本从 "bun --watch run ..." 改为 "bun --hot run ..." | 启用 Bun 原生 HMR,绕过 inotify 兼容性陷阱 |
| 2. 增强 Docker 配置 | docker-compose.yml 添加 volumes: ...:delegated + ulimits/sysctls | 提升 WSL2 文件系统事件传递可靠性 |
| 3. 升级运行时版本 | 使用 oven/bun:1.3.0-slim(非 1.0.3) | 获取 2025 年发布的 HMR 稳定性补丁与 Windows/WSL2 专项优化 |
完成上述配置后,你在 Windows 文件资源管理器中修改 api/src/index.ts 或 web/src/pages/index.astro,Bun 容器将在











