Docker Compose Watch 热重载实战:从30秒手动重建到2秒自动同步
为什么放弃 bind mount + restart
原来的 docker-compose.yml 写法很标准:volumes 把 ./src 挂进容器,然后 docker compose up 跑着。问题是 Python 项目加了新依赖(requirements.txt 改了),bind mount 只同步文件,不触发 pip install。每次加依赖都要手动停容器、build、重启,平均 30 秒。
Docker Compose v2.22 引入的 watch 模式用 inotify 监听文件变更,支持两种 action:sync 直接同步文件(不重建),rebuild 触发完整重建。代码改了走 sync(0.3 秒),依赖改了走 rebuild(2 秒)。
第一个坑:macOS/Windows 上 watch 没反应
在 Mac 上试了半天,文件改了容器里纹丝不动。原因很简单:Docker Desktop 跑在 Linux VM 里,inotify 事件跨不过 VM 边界。Mac 的 FSEvents 和 Linux 的 inotify 是两套机制,Watch 模式在非 Linux 主机上默认静默失败。
解决方案:加 --poll 标志,用轮询代替 inotify。性能差一点(~1 秒延迟 vs ~0.1 秒),但至少能用。生产环境不建议开 poll,开发环境无所谓。
第二个坑:sync 不会触发依赖安装
改了 requirements.txt,watch 检测到文件变更,走了 sync action——文件同步进去了,但 pip install 没跑。容器里 import httpx 直接 ModuleNotFoundError。
原因:sync 只做文件复制,不执行任何构建步骤。requirements.txt 变了必须用 rebuild action。配置里要分开写:src 目录走 sync(快速),依赖文件走 rebuild(完整重建)。
第三个坑:rebuild 的 2 秒其实不算慢
本来以为 rebuild 很慢,实测一个标准 Python 项目从触发 rebuild 到容器 ready 只要 1.8 秒。因为 Docker 的层缓存还在,只要 Dockerfile 没变,只重新跑 pip install 那一层。对比手动 docker compose up --build 的 20-30 秒,2 秒已经是质的飞跃。
配置示例
services:
api:
build: .
develop:
watch:
- action: sync
path: ./src
target: /app/src
- action: rebuild
path: ./requirements.txt
target: /app/requirements.txt
启动命令:docker compose up --watch(注意是 --watch 不是 watch)。
改代码后 0.3 秒同步,改依赖后 2 秒重建。对比之前每次 30 秒的手动操作,开发体验提升非常明显。
👉 Join MiniMax Token Plan: AI coding acceleration for businesses
👉 Join Xiaomi MiMo Platform: Leading AI model platform with cost-effective inference
👉 Join Aliyun AI: Top AI products with exclusive coupons for business innovation
📌 This article was AI-assisted generated and human-reviewed | TechPassive — An AI-driven content testing site focused on real tool reviews
🔗 Recommended Tools
These are carefully selected tools. Using our affiliate links supports us to keep producing quality content: