os.Getenv 读不到 .env 文件变量是因为它只读系统环境变量,不自动加载 .env;需用 godotenv.Load() 显式解析并注入,且须在 main() 开头调用、加校验、避免生产环境误用。

为什么 os.Getenv 读不到 .env 文件里的变量
os.Getenv 只读系统环境变量,不自动加载 .env 文件。你执行 go run main.go 时,Shell 并未把 .env 里内容注入进程环境,所以 os.Getenv("DB_URL") 返回空字符串是正常现象,不是代码写错了。
推荐用 godotenv 加载 .env 文件
Go 生态中稳定、轻量、无依赖的方案是 github.com/joho/godotenv。它只做一件事:解析 .env 文件并调用 os.Setenv 注入当前进程。
- 安装:
go get github.com/joho/godotenv - 放在
main()开头,且必须在任何使用os.Getenv的逻辑之前:func main() { _ = godotenv.Load() // 默认加载 ./\.env // 或指定路径:godotenv.Load(".env.production") app := fiber.New() // 后续可安全调用 os.Getenv("PORT") } - 注意:
godotenv.Load()不报错不等于加载成功——它对格式错误(如空格、未闭合引号)常静默跳过,建议加简单校验:if port := os.Getenv("PORT"); port == "" { log.Fatal("missing PORT in .env") }
Fiber 应用中读取配置的典型位置和顺序
别把配置读取逻辑散落在 handler 里。统一收口到启动阶段,避免重复解析或竞态。
- 优先级应为:
os.Getenv(运行时覆盖) >godotenv.Load()(开发/测试) > 硬编码默认值 - 常见模式:
port := os.Getenv("PORT") if port == "" { port = "3000" } app.Listen(":" + port) - 数据库连接字符串等敏感配置,务必检查非空:
dbURL := os.Getenv("DATABASE_URL"); if dbURL == "" { log.Fatal("DATABASE_URL required") } - 不要在中间件里调用
godotenv.Load()—— 它会重复执行,且可能被并发调用破坏环境变量状态
生产环境该不该用 .env 文件
不该。Kubernetes、Docker、云平台都通过原生方式注入环境变量(如 envFrom: secretRef),.env 是纯开发便利工具。上线前必须确认:os.Getenv 读到的是平台注入的值,而不是本地 .env 的残留。
最容易被忽略的一点:CI/CD 流水线里若没禁用 godotenv.Load(),它会尝试读取空的 .env,然后用默认值覆盖真实配置,导致线上连错数据库或监听错端口。上线前删掉或用条件编译包裹:
if os.Getenv("ENV") == "development" {
_ = godotenv.Load()
}


















