Buffalo dev 默认加载项目根目录的 .env 文件,但仅当文件存在、格式合法(LF换行、无空格/特殊字符、无语法错误)时才生效;否则静默失败,GO_ENV 和 DB_URL 仍为空,且运行中修改不生效。

buffalo dev 为什么没读 .env 文件
因为 buffalo dev 默认只在启动时加载项目根目录下的 .env,但前提是它必须存在且格式合法;如果文件里有语法错误(比如漏了引号、用了中文冒号),整个加载会静默失败,GO_ENV 或 DB_URL 就还是空的。常见现象是终端里 echo $GO_ENV 为空,但你明明写了 .env —— 实际上 buffalo 没读进去。
验证是否加载成功:在 .env 里加一行 ENV_TEST=loaded,然后在 handler 里打印 os.Getenv("ENV_TEST"),输出空字符串就说明没加载。
-
.env文件必须用 Unix 换行符(LF),Windows 的 CRLF 会导致解析中断 - 变量名不能含空格或特殊字符,
DB_URL = ...中的等号两边有空格会失效 -
buffalo dev启动后改.env不生效,必须重启命令
GO_ENV 和 DB_URL 必须在进程启动前设好
GO_ENV 不是运行时开关,而是构建/启动瞬间决定行为分支的“编译期常量”;DB_URL 更是 models.NewDB() 初始化时直接调用 os.Getenv("DB_URL") 获取的——进程一跑起来,这两个值就锁死了。
所以别指望在代码里 os.Setenv("GO_ENV", "production") 能切换环境,也别在 buffalo dev 运行中改 DB_URL 然后 reload,都不起作用。
- 开发时推荐 shell 导出:
export GO_ENV=development; export DB_URL="postgres://..."; buffalo dev - Docker Compose 中写死:
environment: - GO_ENV=production - DB_URL=postgres://... - CI/CD 流水线必须显式注入,不能依赖
.env文件
buffalo build 完全不看 .env,只认环境变量
buffalo build 启动时不加载任何外部文件,.env 对它完全透明。如果你在 .env 里写了 GO_ENV=production,但执行的是 buffalo build,那 app.Env 依然是空字符串或默认 development,导致生产构建逻辑没触发。
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
典型后果:静态资源没打包进二进制、CSRF 中间件没启用、日志不压缩——全是因为构建时没拿到正确的 GO_ENV。
- 正确做法:
GO_ENV=production buffalo build,或者env GO_ENV=production buffalo build - Makefile 里要
export GO_ENV=production,否则子 shell 不继承 - Dockerfile 中必须写
ENV GO_ENV=production,不能靠docker run -e
不同环境共用一套 DB_URL 配置容易踩坑
很多人以为只要 DB_URL 里数据库名不同(比如 myapp_development vs myapp_production)就能自动区分环境,其实不是。Buffalo 的迁移、连接、甚至 buffalo db create 命令,都只认当前环境变量里的 DB_URL,不会根据 GO_ENV 自动拼接。
结果就是:你在 development 下跑了 buffalo db migrate,但 DB_URL 指向的是 production 库,直接把线上表结构改崩了。
- 开发时用独立 URL:
export DB_URL="postgres://.../myapp_development" - 测试环境单独开一个 URL:
export DB_URL="postgres://.../myapp_test" - 生产部署前务必确认
DB_URL指向正确库,且权限最小化(只读 or 仅 DML)
复杂点在于:这些变量不是“配置”,而是启动上下文的一部分。一旦进程起来,再怎么改 shell 变量、重载文件、甚至改代码里的 os.Setenv,都影响不到已经初始化的 app.Pop 或中间件行为。

















