Skip to content

Tracing the Caddy Config Engine Lifecycle

This guide covers Caddy's core configuration lifecycle in caddy.go, explaining how Caddy loads, updates, and swaps server configurations with zero downtime.


The Configuration Cycle

The lifecycle of a Caddy configuration revolves around these primary functions in caddy.go:

Load() ──> changeConfig() ──> unsyncedDecodeAndRun() ──> run() ──> provisionContext()

1. Entering the Engine: Load

  • Code Location: caddy.go:L115
  • What it does: Entry point called by command handlers (like cmdRun or cmdReload). It notifies the system service manager that a reload is occurring and calls changeConfig(...).

2. Guarding the State: changeConfig

  • Code Location: caddy.go:L158
  • What it does:
  • Acquires a global lock (rawCfgMu.Lock()) to prevent multiple configuration changes from running at the same time.
  • Compares the new config with the currently running config. If they are identical, it skips reloading to save CPU.
  • Indexes all objects with unique IDs (e.g. @id fields).
  • Hands off compilation and execution to unsyncedDecodeAndRun(...).

3. Decoding and Swapping: unsyncedDecodeAndRun

  • Code Location: caddy.go:L337
  • What it does:
  • Strips any helper metadata fields (like @id tags) from the raw JSON bytes.
  • Decodes the JSON into the Go struct pointer newCfg *Config.
  • Calls run(newCfg, true) to provision and start the new server.
  • The Zero-Downtime Swap: Once the new configuration starts successfully, it stops and cleans up the old configuration by calling unsyncedStop(oldCtx).
  • Persists the successfully loaded configuration to disk (autosaved as autosave.json).

4. Booting and Starting: run

  • Code Location: caddy.go:L419
  • What it does:
  • Calls provisionContext to initialize storage, loggers, filesystems, and admin HTTP endpoints.
  • Iterates through all apps defined in the config (e.g., http, tls) and starts them:
    for name, a := range ctx.cfg.apps {
        err := a.Start() // Launches each app
    }
    
  • Failure Safety: If any app fails to start, run instantly catches the error, rolls back the configuration, stops any already-started apps, and keeps the old Caddy configuration running uninterrupted.

5. Setting up Execution Environment: provisionContext

  • Code Location: caddy.go:L484
  • What it does: Creates a brand new caddy.Context representing the lifecycle of this config. It opens logs, sets up certificate storage directories, starts the admin endpoint listener, and calls Provision on each application's modules.