buffalo build生成的可执行文件默认打包public/资源但不嵌入templates/,需加--static参数才将模板嵌入二进制;否则运行时调用c.Render()会因找不到模板panic。

buffalo build 生成可部署二进制
Buffalo 不靠 buffalo install 或 buffalo deploy 部署,它用 buffalo build 输出一个自包含的可执行文件。这个命令默认会把 public/ 下静态资源打包进二进制,但 templates/ 默认不嵌入——除非你加 --static 参数。
常见错误现象:buffalo build 后运行二进制报 template: "index.html" not found,或启动时 panic 在 app.ServeFiles();这是因为没加 --static,又删了 templates/ 目录,但代码里还调用了 c.Render()。
- 纯 API 项目(
buffalo new myapp --api)必须删掉templates/、assets/、webpack.config.js,否则buffalo build会卡在前端构建阶段 - 跨平台构建必须设环境变量:
GOOS=linux GOARCH=amd64 buffalo build --static,否则 macOS 上构建的产物无法在 Kubernetes 的 Linux 容器中运行 - 确认是否真静态链接:运行
ldd ./myapp,输出not a dynamic executable才算成功;若显示一堆libgcc或libc,说明没真正静态化
buffalo start 启动生产服务
buffalo start 是生产模式下的运行命令,它跳过热重载、禁用源码监听、关闭开发中间件(如 CSRF 调试头),行为接近直接 ./myapp。但它仍会尝试读取当前目录下的 database.yml 和 env 文件,不会从二进制里读配置。
容易踩的坑:buffalo start 启动后访问 500,日志里出现 failed to open database.yml: no such file or directory——这不是 bug,是 Buffalo 强制从工作目录加载配置,不是从 embed 或二进制内部。
- 必须确保运行
./myapp或buffalo start时,pwd下有database.yml(哪怕只是空文件或最小配置) - 敏感配置(如数据库密码)不要硬编码在
database.yml中,改用环境变量占位:url: {{envOr "DATABASE_URL" "sqlite3://./development.sqlite"}} -
buffalo start不支持-p指定端口,端口由actions/app.go中app.Port = 3000控制;改端口只能改代码再 rebuild
buffalo db migrate 不该在容器启动时自动执行
Kubernetes 或 Docker Compose 环境下,buffalo db migrate 绝对不能写在应用启动命令里(比如 buffalo start && buffalo db migrate)。Buffalo 的迁移命令依赖 CLI 工具链和本地 database.yml,而生产镜像里通常不带 buffalo 二进制,只带编译好的 ./myapp。
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
典型失败表现:容器反复重启,日志里循环打印 command not found: buffalo 或 no such file or directory: database.yml。
- 正确做法是拆出独立 migration Job:用同版本 Go 基础镜像,COPY
database.yml和migrate脚本,执行go run main.go migrate up(如果你用 GORM 或 sql-migrate) - 如果坚持用 Buffalo 自带迁移,得在 Dockerfile 里多装一次 CLI:
RUN go install github.com/gobuffalo/cli/cmd/buffalo@v0.18.1,但体积增大、攻击面变宽,不推荐 - 所有迁移脚本必须幂等;Buffalo 的
buffalo db migrate本身支持重复执行,但自定义 SQL 迁移里别写CREATE TABLE IF NOT EXISTS以外的 DDL,否则可能失败
如何验证部署产物是否可用
部署前最后一道检查,不是看 buffalo version,而是直接跑二进制并探测健康端点。Buffalo 默认不暴露 /healthz,你得自己加——否则 K8s livenessProbe 会永远失败。
很多团队卡在这步:镜像构建成功、容器起来、端口监听了,但 readinessProbe 一直 failing,最后发现是没实现健康检查路由。
- 在
actions/app.go的App()函数末尾加:app.GET("/healthz", func(c buffalo.Context) error { return c.Render(200, nil) }) - 用
curl -v http://localhost:3000/healthz测试,返回 200 且无 body 即通过 - 如果用
--static构建,确保templates/已清空或仅保留healthz.plush(否则c.Render()会因找不到模板 panic)
真正难的不是命令怎么敲,而是哪些东西不该进镜像、哪些配置必须抽离、哪些 panic 只在容器里才触发——这些细节没在 buffalo help 里写,但每次部署失败都在提醒你。

















