推荐直接复用golang:1.22-alpine镜像,通过volumes挂载项目目录和vendor、设置working_dir为/app、绑定0.0.0.0:8080、启用stdin_open/tty、用reflex实现热重载、暴露2345端口并配置Delve调试。
本地开发不需要镜像长期驻留,重点是快速启动、支持热重载、能访问宿主机代码。直接复用 golang:1.22-alpine 基础镜像即可,避免自己写 Dockerfile 增加维护成本。
关键配置点:
volumes 必须挂载当前项目目录(如 ./:/app),否则容器内看不到源码working_dir: /app 要显式设置,否则 go run 可能因路径错乱报 no Go files in current directory
8080:8080 后再用 localhost:8080 测试——Go 服务默认绑定 127.0.0.1:80
80,容器内 127.0.0.1 指向自身,必须改成 0.0.0.0:8080
stdin_open: true 和 tty: true,否则 go run 交互式输入会卡住Go 模块依赖若混用宿主机 go.mod 和容器内缓存,容易出现 cannot find module providing package。最稳做法是把 vendor/ 目录也挂进容器,并在启动时强制启用 vendor 模式。
实操建议:
go mod vendor 生成 vendor/ 目录docker-compose.yml 的 volumes 中增加一行:./vendor:/app/vendor:ro
go run -mod=vendor main.go,避免容器内 GOPATH 或 GOCACHE 干扰$HOME/go/pkg 到容器——不同 Go 版本的缓存不兼容,反而引发 invalid module cache
Docker Compose 本身不监听文件变化,得靠工具触发重建。Go 生态里 reflex 比 nodemon 更轻量、无 Node.js 依赖,适合嵌入容器。
步骤如下:
Dockerfile(或直接用 command)安装 reflex:apk add --no-cache reflex
command 改为:reflex -r "\\.go$" -- sh -c "go run -mod=vendor main.go"
-r 后面的正则要加引号,否则 shell 在 compose 解析阶段就展开失败reflex: command not found,检查是否在 alpine 镜像中用了 apk add 而非 go install(后者需配 GOPATH,易出错)想用 VS Code 远程调试容器内 Go 程序,必须暴露 Delve 的调试端口(默认 2345),且 Delve 启动参数不能绑定到 127.0.0.1。
关键项:
docker-compose.yml 加 ports: ["2345:2345"]
--headless --continue --accept-multiclient --api-version=2 --addr=0.0.0.0:2345
launch.json 中 port 填 2345,host 填 localhost(不是容器名)dlv dap 模式——它需要额外的 WebSocket 端口,Docker Compose 端口映射不支持动态端口分配网络模式用默认 bridge 就够,不需要 network_mode: host;后者会让容器共享宿主机网络栈,反而干扰本地调试端口冲突判断。