Documentation
¶
Overview ¶
Package config 负责加载与校验运行配置。
优先级(后者覆盖前者):内置默认值 → config.yaml → LUMO_* 环境变量。 数据库 DSN 只接受环境变量 LUMO_DATABASE_DSN,口令不得写入配置文件。
Index ¶
Constants ¶
const DefaultUpdateImage = "ghcr.io/feibaikin/lumo"
DefaultUpdateImage 是官方容器镜像,容器部署的升级指引按它拼标签。
const DefaultUpdateRepo = "FeiBaiKin/Lumo"
DefaultUpdateRepo 是在线升级的默认更新源,即本项目的官方仓库。
const EnvPrefix = "LUMO_"
EnvPrefix 是所有环境变量覆盖项的统一前缀。
const InstallFileName = "install.json"
InstallFileName 是安装向导的产物文件名,位于工作目录下。
不写进 config.yaml 是因为 DatabaseConfig.DSN 刻意不带 yaml 标签:配置文件一旦 接受口令,它就会跟着版本库与配置备份到处走。这个文件权限 0600,且与 data/ 同生共死。
Variables ¶
This section is empty.
Functions ¶
func InstallStatePath ¶ added in v0.1.1
InstallStatePath 返回安装产物文件的路径。dataDir 为空时用内置默认值。
func RedactDSN ¶ added in v0.1.1
RedactDSN 脱敏任意连接串。
与 Config.RedactedDSN 同源:安装向导手里只有一条待验证的候选连接串, 还没有落成配置,但同样不能把口令写进日志与接口响应。
func SaveInstallState ¶ added in v0.1.1
func SaveInstallState(dataDir string, state *InstallState) error
SaveInstallState 写入安装产物。
先写同目录的临时文件再改名:进程若在写一半时被杀,下次启动读到的要么是旧内容、 要么是新内容,不会是截断的半截 JSON —— 那会让站点既起不来也重装不了。
Types ¶
type Config ¶
type Config struct {
Server ServerConfig `yaml:"server"`
Database DatabaseConfig `yaml:"database"`
Log LogConfig `yaml:"log"`
Update UpdateConfig `yaml:"update"`
// DataDir 是运行时工作目录,内含 themes/uploads/cache/logs/backups。
DataDir string `yaml:"dataDir"`
}
Config 是全部运行配置的根。
func Load ¶
Load 按「默认值 → 配置文件 → 环境变量 → 安装向导产物」的顺序装配配置并校验。
path 为空时按约定依次尝试 ./config.yaml、./config.yml;文件不存在不算错误, 因为「仅靠环境变量运行」是容器部署的常见形态。
func (*Config) DataSubdir ¶
DataSubdir 返回工作目录下某个子目录的路径。
func (*Config) RedactedDSN ¶
RedactedDSN 返回去掉口令的 DSN,供日志输出使用。 无法解析时返回固定占位串,绝不回落到原始 DSN,以免口令泄漏进日志。
func (*Config) RequireDSN ¶
RequireDSN 在需要数据库的场景校验 DSN 已配置且形态正确。
单独成方法而非并入 Validate:serve 在未配置数据库时也应能启动到给出明确指引, 而 migrate 这类命令必须强制要求 DSN。
type DatabaseConfig ¶
type DatabaseConfig struct {
DSN string `yaml:"-"`
MaxOpenConns int `yaml:"maxOpenConns"`
MaxIdleConns int `yaml:"maxIdleConns"`
ConnMaxLifetime time.Duration `yaml:"connMaxLifetime"`
// MigrationLockTimeout 是等待迁移 advisory lock 的上限。
//
// 多个实例同时启动时,未拿到锁的实例必须等待而不是跳过迁移;但等待不能
// 无限期(数据库黑洞、残留会话等都会让它永久挂起),超时即报错退出。
MigrationLockTimeout time.Duration `yaml:"migrationLockTimeout"`
// AutoMigrate 控制启动时是否自动执行迁移,可被 --no-migrate 关闭。
AutoMigrate bool `yaml:"autoMigrate"`
}
DatabaseConfig 是数据库连接配置。
DSN 故意不带 yaml 标签:它只能来自环境变量,避免口令进入入库文件。
type InstallDatabase ¶ added in v0.1.1
type InstallDatabase struct {
// DSN 含口令,故整个文件按 0600 保存,日志里一律经 RedactedDSN 输出。
DSN string `json:"dsn"`
}
InstallDatabase 是数据库连接信息。
type InstallSite ¶ added in v0.1.1
InstallSite 是安装时填写的站点信息。
type InstallState ¶ added in v0.1.1
type InstallState struct {
// Installed 为真表示向导已经跑完。它是「向导已关闭」的唯一凭据。
Installed bool `json:"installed"`
InstalledAt time.Time `json:"installedAt"`
// Version 是执行安装时的程序版本,便于日后排查。
Version string `json:"version"`
// Database 是向导填写的数据库连接信息。
Database InstallDatabase `json:"database"`
// Site 是向导里填的站点信息,安装时已写入 settings,这里留档备查。
Site InstallSite `json:"site"`
}
InstallState 是安装向导写下的产物。
func LoadInstallState ¶ added in v0.1.1
func LoadInstallState(dataDir string) (*InstallState, error)
LoadInstallState 读取安装产物。
文件不存在返回 (nil, nil):没装过是正常状态而不是错误,调用方不必先 Stat。
type LogConfig ¶
type LogConfig struct {
// Level 取值 debug / info / warn / error。
Level string `yaml:"level"`
// Format 取值 text / json。**只作用于控制台**:写进文件的那一路一律是 JSON,
// 后台日志页要把每行解析成结构化字段。
Format string `yaml:"format"`
// File 为真时在控制台之外再写一份到 dataDir/logs,后台日志页读的就是它。
// 关掉它日志页会是空的,但 docker logs 与 journalctl 不受影响。
File bool `yaml:"file"`
// RetainDays 是日志文件保留天数,超期的在跨天时删除。
RetainDays int `yaml:"retainDays"`
// MaxSizeMB 是单个日志文件的大小上限,超过则在同一天内滚到下一个序号。
MaxSizeMB int `yaml:"maxSizeMB"`
}
LogConfig 是日志配置。
type ServerConfig ¶
type ServerConfig struct {
Addr string `yaml:"addr"`
// ExternalURL 是站点对外可访问地址,用于生成 canonical、sitemap 等绝对链接。
ExternalURL string `yaml:"externalUrl"`
ReadHeaderTimeout time.Duration `yaml:"readHeaderTimeout"`
WriteTimeout time.Duration `yaml:"writeTimeout"`
IdleTimeout time.Duration `yaml:"idleTimeout"`
ShutdownTimeout time.Duration `yaml:"shutdownTimeout"`
// TrustedProxies 是可信反向代理的 CIDR 列表。
//
// 只有当直连对端属于这些网段时,X-Forwarded-For 才被采信。
// 留空表示不信任任何代理,一律使用直连地址——这是最安全的默认值。
TrustedProxies []string `yaml:"trustedProxies"`
// SecureCookies 决定会话 Cookie 是否带 Secure 属性并启用 __Host- 前缀。
// 生产环境(HTTPS)必须为 true;本地 HTTP 开发需为 false,否则浏览器不接受 Cookie。
SecureCookies bool `yaml:"secureCookies"`
// MaxBodySize 是普通请求体的字节上限。
MaxBodySize int64 `yaml:"maxBodySize"`
// MaxUploadSize 是 multipart 请求(附件上传)的字节上限。
//
// 与 MaxBodySize 分开是因为二者的取舍相反:JSON 接口越小越好,
// 而附件动辄几十兆,用同一个值要么挡住正常上传,要么给所有接口放开口子。
MaxUploadSize int64 `yaml:"maxUploadSize"`
}
ServerConfig 是 HTTP 服务配置。
type UpdateConfig ¶ added in v0.1.3
type UpdateConfig struct {
// Enabled 为假时整个功能关闭:不做后台检查,接口一律 409。
// 由发行方统一升级的部署(容器编排、包管理器)应当关掉它。
Enabled bool `yaml:"enabled"`
// AutoCheck 控制是否在后台定期检查新版本。关掉它仍可在后台手动检查。
AutoCheck bool `yaml:"autoCheck"`
// CheckInterval 是后台检查的间隔。
//
// 下限 1 小时:GitHub 对未认证请求按 IP 限 60 次/小时,
// 同一出口下的多个站点把这个值调小会一起被限流。
CheckInterval time.Duration `yaml:"checkInterval"`
// Prerelease 为真时把预发布版本也算作可升级目标。
Prerelease bool `yaml:"prerelease"`
// AllowInContainer 允许在容器里就地替换二进制。
//
// 默认关闭,因为换掉的文件活在容器的可写层里:`docker restart` 不丢,
// 但**重建容器**(改配置、拉新镜像、compose up --force-recreate)会回到
// 镜像里的版本,而站长多半不会把「我上个月改过端口」和「版本怎么退回去了」
// 联系起来。
//
// 开着它是一个有意义的取舍:配一次之后就能在后台一键升级,不必每次去换镜像
// 标签。代价由版本回退检测兜住——真回退了,日志与后台都会说出来(见 state.go)。
AllowInContainer bool `yaml:"allowInContainer"`
// Image 是容器部署的镜像地址,用来在后台给出「该换成哪个标签」。
Image string `yaml:"image"`
// Repo 是更新源仓库,形如 owner/name。
//
// 可配置是为了让 fork 与内网镜像能自管升级;默认指向官方仓库。
// 改它等于改「这台机器信任谁发布的二进制」,故只接受配置文件与环境变量。
Repo string `yaml:"repo"`
// APIBase 是更新源的 API 根地址,留空即 GitHub 公有云。
//
// 只走环境变量 LUMO_UPDATE_API_BASE,与 Repo 是同一件事的两半:
// 指向自建镜像或 GitHub Enterprise 的部署要改它。不写进配置文件是因为
// 它决定「这台机器去哪里取二进制」,属于部署环境而非站点配置。
APIBase string `yaml:"-"`
// Token 是访问 GitHub API 的令牌,可留空。
//
// 只走环境变量 LUMO_UPDATE_TOKEN,理由同 DSN:凭据不写进入库文件。
// 用途是抬高限流阈值或访问私有仓库,公开仓库不需要它。
Token string `yaml:"-"`
// KeepBackups 是升级成功后保留的旧版本备份份数,0 表示不自动清理。
KeepBackups int `yaml:"keepBackups"`
}
UpdateConfig 是在线升级配置。
升级是运维动作而非站点设置:它取决于「这份二进制装在哪、谁能写它」, 换台机器部署结论就变了,故放在配置文件与环境变量里,而不是入库的设置表。