Tilt默认不自动重启Go进程,仅同步文件;需配合air等热重载工具,并在live_update中配置sync路径、run命令及完整模块路径映射,否则改代码无反应。

为什么 tilt up 后 Go 服务没热重载?
Tilt 默认不自动重启 Go 进程,它只同步文件——但 go run 启动的进程不会监听文件变化。你改完代码、看到 Tilt 显示 “file synced”,服务却还是旧逻辑,这是最常卡住的第一步。
- 必须用支持热重载的启动方式:
air、reflex或fresh,而不是裸go run main.go - Tilt 的
live_update块里不能只写sync,还得配trigger和restart_container(对纯二进制部署)或run(对进程内热重载) - Go 模块路径错误会导致
air找不到入口文件,报no Go files found——检查air.toml中的root和bin是否指向正确模块根目录
tilt.yaml 中怎么写 Go 服务的 live_update?
别套用 Python/JS 的 sync 模式。Go 编译产物是静态二进制,本地开发时更推荐“源码+热重载工具”组合,而非反复 go build + docker cp。
- 用
air作为容器内进程:Dockerfile 里CMD ["air"],确保air.toml在镜像内且路径正确 - Tilt 配置中禁用默认构建触发:
build: { dockerfile: null },改用live_update直接 rsync 源码 -
sync路径必须是容器内可写路径(如/app),且与air.toml的root一致;否则air不会扫描变更 - 示例片段:
live_update:<br> - sync: ["./cmd/myapi/:/app/"]<br> run: ["sh", "-c", "cd /app && air -c air.toml"]
如何避免 Tilt + Go 下的 import 路径错乱?
本地 GOPATH 或 go.mod 路径和容器内不一致,会导致 air 编译失败,报错如 cannot load github.com/xxx/yyy: cannot find module providing package。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 所有 Go 项目必须启用
go modules(GO111MODULE=on),且go.mod在项目根目录(即 tilt.yaml 同级) - Tilt 的
sync必须包含go.mod和go.sum,否则容器内air无法 resolve 依赖 - 如果用 vendor,确保
sync包含/vendor目录,且air.toml中设tmp_dir = "./.air"避免写入只读层 - 容器内执行
go env GOPROXY,若为direct且网络受限,需在 Dockerfile 或run命令中显式设置GOPROXY=https://proxy.golang.org
为什么改了 internal/ 包,Tilt 却不触发更新?
Tilt 默认只监听 sync 列表里的路径,而 internal/、pkg/ 这类共享包常被漏掉——改了它们,主服务却没重启,逻辑不同步。
立即学习“go语言免费学习笔记(深入)”;
-
sync必须显式列出所有参与编译的路径,例如:["./cmd/myapi/:/app/", "./internal/:/app/internal/", "./pkg/:/app/pkg/"] - 不要依赖通配符(如
**/*.go),Tilt 的 sync 不支持 glob,只认明确路径映射 - 如果用多 module 结构(比如 monorepo 下多个 go.mod),每个 module 都要单独配置
live_update,Tilt 不会跨目录自动推导依赖关系 - 验证方法:改一个
internal/xxx/yyy.go,观察 Tilt 日志是否出现Syncing file: internal/xxx/yyy.go → /app/internal/xxx/yyy.go
Tilt 对 Go 的秒级同步不是开箱即用的魔法,它依赖你把 Go 工程结构、模块路径、热重载工具链这三层对齐;任一环错位,就会退回“保存→等待构建→手动 curl 测试”的老路。

















