Docker环境使用cosmtrek/air时Go应用自动重载不触发重建问题
Docker环境下cosmtrek/air无法触发Go应用热重载问题
问题描述
Windows 10主机本地直接运行cosmtrek/air时可正常触发Go代码重建、完成热重载;将air部署到Docker容器运行后,进入容器确认挂载卷内的代码文件已随宿主机修改同步更新,但air始终不触发代码重建,也不输出新代码的运行日志,本地运行不存在该问题。
项目文件结构
-cmd -api -main.go .air.toml docker-compose.dev.yml Dockerfile.dev go.mod go.sum
现有配置
Dockerfile.dev
FROM golang:1.18.3-alpine3.15 WORKDIR /app COPY go.mod go.sum /app/ RUN go mod download && go mod verify RUN go install github.com/cosmtrek/air@latest COPY ./ /app/ CMD "air"
docker-compose.dev.yml
version: '3.8' services: backend: container_name: go-backend-test build: context: . dockerfile: ./Dockerfile.dev volumes: - ./:/app
.air.toml
root = "." testdata_dir = "testdata" tmp_dir = "tmp" [build] args_bin = [] bin = "tmp/main.exe" cmd = "go build -o ./tmp/main.exe ./cmd/api/." delay = 1000 exclude_dir = ["assets", "tmp", "vendor", "testdata"] exclude_file = [] exclude_regex = ["_test.go"] exclude_unchanged = false follow_symlink = false full_bin = "" include_dir = [] include_ext = ["go", "tpl", "tmpl", "html"] kill_delay = "0s" log = "build-errors.log" send_interrupt = false stop_on_error = true [color] app = "" build = "yellow" main = "magenta" runner = "green" watcher = "cyan" [log] time = false [misc] clean_on_exit = true [screen] clear_on_rebuild = true
容器运行日志

解决步骤
- 修正Linux环境下的二进制命名错误:当前基础镜像为Alpine Linux,可执行文件不需要
.exe后缀,将.air.toml中bin = "tmp/main.exe"修改为bin = "tmp/main",对应构建命令修改为cmd = "go build -o ./tmp/main ./cmd/api/.",避免二进制文件命名异常导致运行失败。 - 修复Docker跨系统挂载的文件事件丢失问题:Windows宿主机NTFS目录挂载到Linux容器时,系统原生inotify文件变更事件无法被容器内进程正常捕获,air默认依赖inotify触发构建,因此会出现文件已同步但不触发重建的现象。在.air.toml的
[build]配置段添加如下参数,开启主动轮询模式监听文件变化:
配置后air会每隔500ms主动扫描文件变更,不依赖系统inotify事件,可适配跨系统挂载卷场景。poll = true poll_interval = 500 - 优化挂载卷配置:在docker-compose.dev.yml的volumes配置中新增匿名卷挂载,将容器内的临时构建目录与宿主机隔离,减少不必要的文件同步开销,避免临时文件冲突:
volumes: - ./:/app - /app/tmp - 修正Dockerfile的CMD指令写法:将
CMD "air"修改为CMD ["air"],避免shell格式解析错误导致air启动时配置加载异常。
内容的提问来源于stack exchange,提问作者Vimal Kurien Sam
相关产品推荐
相关产品推荐

