config

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 26, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package config 负责加载与校验运行配置。

优先级(后者覆盖前者):内置默认值 → config.yaml → LUMO_* 环境变量。 数据库 DSN 只接受环境变量 LUMO_DATABASE_DSN,口令不得写入配置文件。

Index

Constants

View Source
const DefaultUpdateImage = "ghcr.io/feibaikin/lumo"

DefaultUpdateImage 是官方容器镜像,容器部署的升级指引按它拼标签。

View Source
const DefaultUpdateRepo = "FeiBaiKin/Lumo"

DefaultUpdateRepo 是在线升级的默认更新源,即本项目的官方仓库。

View Source
const EnvPrefix = "LUMO_"

EnvPrefix 是所有环境变量覆盖项的统一前缀。

View Source
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

func InstallStatePath(dataDir string) string

InstallStatePath 返回安装产物文件的路径。dataDir 为空时用内置默认值。

func RedactDSN added in v0.1.1

func RedactDSN(dsn string) string

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 Default

func Default() Config

Default 返回内置默认配置。

func Load

func Load(path string) (Config, error)

Load 按「默认值 → 配置文件 → 环境变量 → 安装向导产物」的顺序装配配置并校验。

path 为空时按约定依次尝试 ./config.yaml、./config.yml;文件不存在不算错误, 因为「仅靠环境变量运行」是容器部署的常见形态。

func (*Config) DataSubdir

func (c *Config) DataSubdir(name string) string

DataSubdir 返回工作目录下某个子目录的路径。

func (*Config) RedactedDSN

func (c *Config) RedactedDSN() string

RedactedDSN 返回去掉口令的 DSN,供日志输出使用。 无法解析时返回固定占位串,绝不回落到原始 DSN,以免口令泄漏进日志。

func (*Config) RequireDSN

func (c *Config) RequireDSN() error

RequireDSN 在需要数据库的场景校验 DSN 已配置且形态正确。

单独成方法而非并入 Validate:serve 在未配置数据库时也应能启动到给出明确指引, 而 migrate 这类命令必须强制要求 DSN。

func (*Config) Validate

func (c *Config) Validate() error

Validate 校验配置的自洽性。

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

type InstallSite struct {
	Title string `json:"title,omitempty"`
	URL   string `json:"url,omitempty"`
}

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 是在线升级配置。

升级是运维动作而非站点设置:它取决于「这份二进制装在哪、谁能写它」, 换台机器部署结论就变了,故放在配置文件与环境变量里,而不是入库的设置表。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL