文档目录
glen
· 预计阅读 3 分钟

第 6 章 配置、路径与运行目录

本文导航
第 6 章 配置、路径与运行目录

第 6 章 配置、路径与运行目录

Owl 的配置不是手写模板,而是「Provider 提供默认值,框架按需落盘,再允许环境变量覆盖」。这一章说明配置从哪里来、怎么改、部署时注意什么。

配置目录在哪里

GetConfigPath() 返回 conf/ 的实际位置,规则是:

先看 可执行文件目录/conf
不存在 → 再看 当前工作目录/conf

GetStoragePath()、GetLangPath() 同理。开发时通常落在项目根目录;以服务方式运行时可能落到可执行文件旁边。部署前先确认。

配置文件怎么生成的

每个 Provider 实现 Conf():

func (i *DBServiceProvider) Conf() map[string]string {
	return map[string]string{"database.yaml": databaseYaml}
}

启动时框架会:

  1. 如果 conf/database.yaml 不存在,写入默认内容;
  2. 如果已存在,把默认内容里缺少的键补到原文件对应位置;
  3. 已有值不改;补不进去的键只告警。

所以升级框架后,旧的配置文件会自动获得新字段,不需要手工对比模板。

读取配置

业务代码通过 *conf.Configure 读取:

type OrderOptions struct {
	CloseUnpaidMinutes int `mapstructure:"close-unpaid-minutes"`
}

func NewOrderService(c *conf.Configure) *OrderService {
	var opt OrderOptions
	if err := c.GetConfig("order", &opt); err != nil {
		// 配置缺失或类型错误
	}
	return &OrderService{opt: opt}
}

GetConfig(key, v) 的 key 是文件名去掉扩展名,例如 order.yaml 对应 order。嵌套字段可以用 order.trade 这种形式。

环境变量覆盖

规则如下:

  • 每个配置文件有前缀,database.yaml → DATABASE_,jwt.yaml → JWT_;
  • 键里的 . 和 - 转成 _,字母转大写;
  • 嵌套配置用 _ 连接。

例如:

# conf/database.yaml
host: 127.0.0.1
port: 5432
username: postgres
password: postgres

对应:

DATABASE_HOST=10.0.0.12
DATABASE_PORT=5432
DATABASE_USERNAME=owl
DATABASE_PASSWORD=secret
# conf/jwt.yaml
signing-key: change-me

对应 JWT_SIGNING_KEY。

嵌套配置:

# conf/rabbitmq.yaml
connection:
  host: localhost

对应 RABBITMQ_CONNECTION_HOST。

.env 文件

框架按优先级加载:

  1. .env.local(最高,且不应提交);
  2. .env.{环境名};
  3. .env。

环境名由 APP_ENV 或 ENVIRONMENT 决定,默认 development。

数据库最小配置

开发期建议先用 SQLite:

# conf/database.yaml
driver: sqlite
host: my-order.db
database: main

SQLite 模式下,host 会拼到配置目录,数据库文件落在 conf/my-order.db。

生产环境用 PostgreSQL 时:

driver: pgsql
host: 127.0.0.1
port: 5432
database: owl
schema: public
username: owl
password: secret
ssl-mode: disable
time-zone: Asia/Shanghai

driver 支持 pgsql、mysql、sqlite。

Redis

需要分布式锁时注册 redis.RedisServiceProvider,并在 conf/redis.yaml 配置:

mode: single
single:
  host: 127.0.0.1
  port: 6379
  password: ""
  database: 0

业务代码通过 redis.LockerFactory 使用:

l := locker.New()
if err := l.Lock("order:create"); err != nil {
	return err
}
defer l.Unlock()

敏感信息怎么放

不要提交 conf/*.yaml 里的密码和密钥。实际项目通常:

  • 仓库只保留 conf/.gitignore,忽略 *.yaml;
  • 部署时由环境变量或配置中心注入;
  • 本地用 .env.local,并确保它在 .gitignore 里。

部署时的路径检查

以 systemd 为例:

[Service]
WorkingDirectory=/opt/owl
ExecStart=/opt/owl/owl-server
  • 可执行文件在 /opt/owl/owl-server,basePath=/opt/owl;
  • 若 /opt/owl/conf 存在,就使用它;
  • 否则回落到工作目录 /opt/owl/conf,结果相同。

如果二进制和配置分开放,例如 ExecStart=/usr/local/bin/owl-server、配置在 /etc/owl/conf,inferDir 不会自动找到 /etc/owl。这时需要确保工作目录正确,或用软链接把配置放到可执行文件目录下。

自检

  • [ ] 知道当前运行使用的是 basePath 还是 runDir;
  • [ ] 新增 Provider 的 Conf() 能被正确写盘;
  • [ ] 敏感配置没有进仓库;
  • [ ] 环境变量前缀和键名转换规则正确;
  • [ ] 部署后 conf/、storage/ 落在预期位置。

评论

加载评论中…

上一篇 第 5 章 路由、菜单与权限标识 下一篇 第 7 章 数据模型与迁移

BitLabs © 2026 · 论坛讨论 · 博客长文 · 文档手册