如何在Docker开发环境配置Gin应用的Air热重载?
在Docker+Docker Compose环境中实现Gin应用的Air热重载解决方案
问题概述
我正在用Gin和Docker搭建后端系统,需要区分开发/生产环境,开发环境想用Air实现热重载。但用docker-compose --env-file .env.development up --build启动后,修改Go文件Air不会自动重建重启,必须手动重建容器才行。
核心原因分析
容器运行的是构建阶段COPY进镜像的代码,本地代码修改后不会同步到容器内部,Air监测不到文件变化,自然不会触发重载。
具体修复步骤
1. 修改Docker Compose配置,挂载本地代码目录
在docker-compose.yml的app服务中添加volumes配置,将本地代码挂载到容器的工作目录,同时排除容器内的临时目录和依赖目录,避免冲突:
services: db: # 保持原有配置不变 app: build: context: . target: ${BUILD_STAGE:-prod} environment: DATABASE_URL: ${DATABASE_URL} JWT_SECRET_KEY: ${JWT_SECRET_KEY} ports: - "8080:8080" depends_on: - db # 添加以下volumes配置 volumes: - ./:/app # 挂载本地代码到容器工作目录 - /app/tmp # 匿名volume,避免本地tmp目录干扰容器内的Air临时文件 - /app/vendor # 可选:避免本地vendor覆盖容器下载的依赖
2. 优化Dockerfile,移除开发阶段的冗余构建步骤
原Dockerfile的base阶段提前构建了应用,开发环境下完全不需要,而且会被挂载的本地代码覆盖。调整后的Dockerfile如下:
# syntax=docker/dockerfile:1.3 # Base stage:仅处理依赖下载 FROM golang:1.22.5-alpine AS base WORKDIR /app COPY go.mod go.sum ./ RUN go mod download # Development stage:安装Air,启动热重载 FROM base AS dev RUN apk add --no-cache git \ && go install github.com/air-verse/air@latest COPY .air.toml ./ CMD ["air"] # Production stage:单独构建生产镜像 FROM base AS prod-build COPY . . RUN go build -o main . FROM alpine:latest AS prod WORKDIR /root/ COPY --from=prod-build /app/main . CMD ["./main"]
3. 调整Air配置,开启文件轮询(可选但推荐)
部分Docker环境下,容器无法通过inotify获取主机的文件变更事件,需要开启轮询模式。在.air.toml中添加[watcher]配置:
# 原配置保持不变,新增以下内容 [watcher] poll = true # 开启轮询,确保Air能监测到文件变化
4. 启动验证
确保.env.development文件中设置BUILD_STAGE=dev,然后重新启动容器:
docker-compose --env-file .env.development up --build
现在修改本地Go文件,就能看到Air自动触发构建和重启了。
内容的提问来源于stack exchange,提问作者Samy
相关产品推荐
相关产品推荐

