Skip to content

Tracing Caddy's Server Boot Flow

This guide walks you step-by-step through how Caddy starts up from a command-line input to launching its core engine.


The Boot sequence

When you run Caddy, the execution flows as follows:

cmd/caddy/main.go (main)
  └── cmd/main.go (caddycmd.Main)
        └── cmd/commands.go (Subcommands registration)
              └── cmd/commandfuncs.go (cmdRun or cmdStart)

Step 1: The OS Entry Point

  • File: cmd/caddy/main.go
  • Code:
    func main() {
        caddycmd.Main()
    }
    
  • Why it's here: Every executable Go program starts here. It also side-effect imports github.com/caddyserver/caddy/v2/modules/standard which registers all Caddy's default components at boot time.

Step 2: CLI Engine Hand-off

  • File: cmd/main.go
  • Code:
    func Main() {
        ...
        if err := defaultFactory.Build().Execute(); err != nil {
            ...
        }
    }
    
  • Why it's here: This function is called by main(). It builds the CLI command structure (using the Cobra library) and parses the incoming OS arguments (e.g. run, start, stop).

Step 3: Command Routing

  • File: cmd/commands.go
  • Why it's here: Defines all available subcommands. It attaches flag options (like --config, --watch, --resume) and registers the functions that should execute for each command.
  • For example, the run command is registered to execute the cmdRun function.
  • The start command is registered to execute the cmdStart function.

Step 4: Execution Logic

  • File: cmd/commandfuncs.go
  • Why it's here: This file contains the implementation of what each command actually does:
  • cmdRun() (cmd/commandfuncs.go:L188): Loads configuration (JSON or adapts Caddyfile), handles signal traps (like Ctrl+C), and calls caddy.Load() to boot the core engine in the foreground.
  • cmdStart() (cmd/commandfuncs.go:L45): Opens a local confirmation socket, launches a subprocess (running caddy run), verifies that the subprocess starts successfully, prints the PID, and exits.
  • cmdStop() (cmd/commandfuncs.go:L356): Connects to the running Caddy server's local HTTP API and sends a POST /stop request to shut it down.
  • cmdReload() (cmd/commandfuncs.go:L376): Sends a POST /load request with a new configuration to the running Caddy instance.