Open-Source Wikis

/

Caddy

/

Systems

/

Admin API

caddyserver/caddy

Admin API

Caddy's running configuration is mutable at runtime through a built-in HTTP API. Default address localhost:2019. Defined in admin.go (~49 KB).

Purpose

Let operators (and other tools) read and replace the running config without restarting Caddy. The same API also exposes module-defined endpoints for inspection: PKI metadata, reverse-proxy upstream health, Prometheus metrics, and pprof handlers.

Directory layout

Path Role
admin.go AdminConfig, AdminRouter interface, route registration, /load and /config handlers, origin enforcement
caddy.go: Load The function /load ultimately calls
modules/caddyhttp/reverseproxy/admin.go Reverse-proxy upstream introspection routes
modules/caddypki/adminapi.go /pki/ endpoints
modules/metrics/ /metrics Prometheus exposition

Key abstractions

Type Where Description
AdminConfig admin.go Top-level config: listen address, origin enforcement, identity (mTLS), remote control
AdminRoute admin.go {Pattern, Handler} registered by module-supplied admin endpoints
AdminRouter admin.go Module interface — Routes() []AdminRoute
adminHandler admin.go Wraps http.ServeMux and applies CORS / origin checks
AdminHandler / AdminHandlerFunc admin.go The handler shape with error returns

How it works

graph TD
    Curl[curl localhost:2019/load] --> Admin
    AdminRouterModule[modules implementing AdminRouter] -->|register at provision| Admin
    Admin -->|dispatch| BuiltIn[/load, /config, /id, /reverse_proxy/upstreams]
    Admin -->|dispatch| Module[/pki/, /metrics]
    Admin -->|enforce| Origin[Origin/Host check]
    BuiltIn -->|JSON in| Loader[caddy.Load]
    Loader --> NewConfig[New Config]
    NewConfig -->|provision/start| Apps
    Loader -->|on failure| Rollback

Origin enforcement

By default the admin endpoint listens on localhost:2019 and rejects requests whose Host or Origin headers don't match the listen address. This is in admin.go's originAllowed checks. Configure with AdminConfig.EnforceOrigin and AdminConfig.Origins. When the listener binds to a non-loopback address, you should also enable client-cert authentication via AdminConfig.Identity.

Built-in routes

Path Method Purpose
/load POST Replace the entire running config
/config/[path...] GET, POST, PUT, PATCH, DELETE Read or surgically edit subtrees of the running config
/id/<id> GET, PUT, DELETE Operate on objects by @id (Caddy supports @id keys for stable refs)
/stop POST Stop the server gracefully
/adapt POST Run a config adapter, return JSON without applying it

The /config/ family lets you do partial updates without uploading a full document — PUT /config/apps/http/servers/srv0/routes/0 swaps a single route in place.

Module-supplied routes

A module exposes admin endpoints by implementing caddy.AdminRouter:

func (m *MyModule) Routes() []caddy.AdminRoute {
    return []caddy.AdminRoute{{
        Pattern: "/myfeature/",
        Handler: caddy.AdminHandlerFunc(m.handle),
    }}
}

During admin server provisioning (admin.go), every module that implements AdminRouter is collected and its routes are added to the mux. Each route's pattern is namespaced — Pattern: "/pki/" becomes localhost:2019/pki/....

Examples in the standard build:

  • modules/caddyhttp/reverseproxy/admin.go registers /reverse_proxy/upstreams (lists upstreams + health).
  • modules/caddypki/adminapi.go registers /pki/ca/<id> and certificate-listing routes.
  • modules/metrics/ registers /metrics (Prometheus).

net/http/pprof is also imported so /debug/pprof/... is exposed when the admin endpoint is up.

/load semantics

POST /load runs the body through caddy.Load:

  1. Hash the new JSON; if it equals the current hash and Cache-Control: must-revalidate isn't set, skip.
  2. Parse into Config, run module provisioning, then app Starts in order.
  3. On any failure, run Cleanup and roll back to the prior running config.
  4. On success, swap the current config under a mutex; emit a structured log line and notify the OS service manager via notify.

Origin enforcement, throttling (one in-flight load at a time), and load-deadline handling all live in admin.go.

Integration points

  • CLI: caddy reload, caddy adapt --validate, and caddy stop all call the admin API rather than implementing the operations again.
  • Modules: any module implementing AdminRouter extends the API surface.
  • Identity: AdminConfig.Identity is a managed cert configured for the admin endpoint itself, used when binding to a public address.

Entry points for modification

  • Add a built-in route? Edit admin.go near the existing /load//config handlers.
  • Add origin/auth checks? originAllowed and the surrounding middleware setup.
  • Add a module-supplied endpoint? Implement AdminRouter on your module — no edits to the core needed.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Admin API – Caddy wiki | Factory