菜单

配置系统

相关源文件

Caddy 的配置系统是管理 Caddy 如何加载、存储、验证和应用配置的核心机制。该系统是 Caddy 运行时行为的基础,它支持在不重启的情况下动态更改配置,并实现了配置表示与操作功能之间的清晰分离。

有关与此配置系统交互的 Admin API 的信息,请参阅 Admin API

概述

Caddy 的配置系统围绕基于 JSON 的 Config 结构体构建,该结构体管理着整个服务器的生命周期。该系统通过适配器支持多种输入格式,其中 Caddyfile 是最常见的人类可读格式,会被转换为 JSON。

核心配置函数

  • Load() - 加载并应用带有安全检查的配置
  • Run() - 直接运行配置,不进行加载验证
  • changeConfig() - 通过 Admin API 处理运行时配置更新
  • unsyncedDecodeAndRun() - 低级别配置加载

来源: caddy.go68-92 caddy.go100-140 caddyconfig/httpcaddyfile/httptype.go57-87

配置结构

Caddy 配置的根基是 Config 结构体。该结构体充当了定义 Caddy 如何运行的所有配置元素的层级容器。

核心配置结构

Config 结构体字段有特定用途

字段类型目的
管理员*AdminConfigAdmin API 端点配置
日志记录*Logging全局日志设置
StorageRawjson.RawMessage存储模块配置(证书等)
AppsRawModuleMap应用程序配置的原始 JSON
appsmap[string]App运行时应用程序实例
storagecertmagic.Storage已提供的存储实现
cancelFunccontext.CancelFunc配置生命周期的清理函数

AppsRaw 字段包含在 provision 过程中加载到 apps 字段的模块配置。每个应用程序提供特定的服务,如 HTTP 处理或 TLS 管理。

来源: caddy.go68-92 admin.go63-118 modules.go122-128

配置加载生命周期

当加载新配置时,Caddy 会遵循一系列步骤,从当前配置安全地过渡到新配置。此过程可确保配置的正确性,并最大程度地减少对运行中服务的影响。

配置加载生命周期

配置加载遵循以下函数调用

  1. StrictUnmarshalJSON(): 将 JSON 解析到带有验证的 Config 结构体
  2. NewContext(): 创建模块生命周期管理上下文
  3. LoadModule(): 使用反射从 AppsRaw 加载每个模块
  4. Module lifecycle: 调用模块的 Provision() 然后 Validate()
  5. App.Start(): 启动每个已提供的应用程序
  6. unsyncedStop(): 清理旧的配置

来源: caddy.go100-140 caddy.go318-384 caddy.go400-453 caddy.go460-556

模块 Provisioning

配置系统与 Caddy 的模块系统紧密集成。当加载配置时,每个模块都会经历一个准备使用其生命周期。

模块 Provisioning

Context.LoadModuleByID() 中的模块加载过程

  1. GetModule(moduleName): 从全局注册表中查找 ModuleInfo
  2. modInfo.New(): 使用构造函数创建新实例
  3. StrictUnmarshalJSON(): 将配置解组到模块实例
  4. Type assertion checks: 确定实现了哪些生命周期接口
  5. Provision(ctx): 授予模块访问资源和其他模块的权限
  6. Validate(): 检查配置的正确性
  7. Store in context: 添加到 ctx.moduleInstances 以进行清理跟踪

模块生命周期接口

  • Provisioner: 设置阶段,可以访问 Context
  • Validator: 配置验证阶段
  • CleanerUpper: 上下文取消时的清理

来源: context.go345-413 modules.go288-316 caddy.go460-556

配置访问和修改

Caddy 提供两种主要方式来访问和修改配置

  1. Admin API: 用于运行时配置管理的 HTTP API
  2. 命令行: 直接加载配置文件

当请求配置更改时,Caddy 会遵循此流程

如果新配置与当前配置相同,Caddy 将避免重新加载的开销。否则,它将尝试加载新配置,同时保留旧配置以防失败。

来源: caddy.go142-262 admin.go217-281

配置适配器

虽然 Caddy 的原生配置格式是 JSON,但它通过适配器支持其他格式。最常见的适配器是 Caddyfile 格式,它提供了更友好的语法。

ServerType.Setup() 中的 Caddyfile 适配器过程

  1. caddyfile.ServerBlock parsing: 将令牌解析为服务器块结构
  2. Directive processing: 通过 registeredDirectives 映射调用已注册的指令函数
  3. buildTLSApp(): 从 TLS 指令构建 TLS 应用程序配置
  4. buildPKIApp(): 构建 PKI 应用程序配置
  5. Server consolidation: 按地址将服务器块分组到 caddyhttp.Server 实例
  6. JSON generation: 使用 AppsRaw 填充后转换为 caddy.Config

主要功能

  • ServerType.Setup(): 主要的 Caddyfile 适配入口点
  • RegisterDirective(): 注册指令解析函数
  • Helper.NewRoute(): 从指令结果创建 HTTP 路由
  • buildSubroute(): 将多个指令合并为路由处理器

来源: caddyconfig/httpcaddyfile/httptype.go57-363 caddyconfig/httpcaddyfile/directives.go109-138 caddyconfig/httpcaddyfile/directives.go276-302

配置持久化

Caddy 可以将配置自动持久化到磁盘。这确保了如果 Caddy 重新启动,它可以恢复其上次运行的配置。

持久化机制

  • 将当前配置写入 JSON 文件
  • 可以通过 persist_config 选项禁用
  • 允许 Caddy 在重启后恢复相同的配置

来源: caddy.go359-381

全局选项系统

配置系统支持影响Caddy整体行为的全局选项。这些选项可以在Caddyfile的全局选项块中设置,也可以直接在JSON配置中设置。

全局选项通过ServerType.evaluateGlobalOptionsBlock()进行处理,并通过RegisterGlobalOption()进行注册。可用选项

选项解析函数目的
debugparseOptTrue启用调试日志
http_portparseOptHTTPPort默认HTTP端口
https_portparseOptHTTPSPort默认HTTPS端口
storageparseOptStorage存储模块配置
adminparseOptAdminAdmin API设置
auto_httpsparseOptAutoHTTPS自动HTTPS行为
logparseLogOptions全局日志配置
orderparseOptOrder指令执行顺序

全局选项存储在options映射中,并在ServerType.Setup()期间使用,以配置生成的caddy.Config结构。

来源: caddyconfig/httpcaddyfile/options.go32-68 caddyconfig/httpcaddyfile/httptype.go369-453

配置加载方法

Caddy提供了多种加载配置的方式

  1. 直接API:调用Run()Load()并传入配置
  2. Admin API:向admin端点发送HTTP请求
  3. 命令行:通过CLI标志从文件加载
  4. 动态加载:定期从外部源拉取配置

动态配置加载机制允许Caddy定期从外部源拉取配置,从而实现基础设施即代码和集中式配置管理场景。

来源: caddy.go100-140 caddy.go586-652

总结

Caddy的配置系统为管理服务器配置提供了一个强大的基础。其主要特点包括:

  1. 基于JSON:统一、结构化的配置格式
  2. 动态重配置:无需重启服务器即可进行更改
  3. 模块化设计:配置映射到模块
  4. 验证:在应用配置之前进行检查
  5. 适配器:支持Caddyfile等人类可读的格式
  6. 持久化:配置可以保存和恢复

该系统实现了Caddy在运行时无需中断即可重新配置自身的能力,使其在生产部署中兼具灵活性和可靠性。