Caddy — API Surface#
API types#
Caddy exposes four distinct API surfaces:
- REST/HTTP Admin API — runtime config management and introspection
- CLI — process lifecycle and tooling
- Plugin/Extension system — the primary surface for extensibility
- Library API — public Go interfaces for embedding or extending
REST/HTTP Admin API#
- Router:
net/httpstdlibServeMuxwrapped inadminHandler - Listen address:
localhost:2019(default, overridable viaCADDY_ADMINenv var or config) - Route registration: Hardcoded routes registered at startup in
admin.go:newAdminHandler(); additional routes from modules in theadmin.apinamespace via theAdminRouterinterface - Middleware chain: Single layer — host/origin enforcement, CORS checking, Prometheus metrics instrumentation, then dispatch to route handlers. Remote admin endpoint adds mutual TLS in front.
- Authentication: Local endpoint: host/origin header verification (opt-in CORS enforcement). Remote endpoint: mutual TLS with certificate-based identity (
IdentityConfig).
Core built-in endpoints#
| Pattern | Methods | Purpose |
|---|---|---|
/config/ | GET, POST, PUT, PATCH, DELETE | Config tree traversal and mutation — the primary admin interface. Path segments map to JSON keys. |
/id/ | GET, POST, PUT, PATCH, DELETE | Access any config node by its @id tag (opaque handle across reloads) |
/stop | POST | Graceful shutdown |
/debug/pprof/ | GET | Go pprof index |
/debug/pprof/cmdline | GET | Process command line |
/debug/pprof/profile | GET | CPU profile |
/debug/pprof/symbol | GET | Symbol lookup |
/debug/pprof/trace | GET | Execution trace |
/debug/vars | GET | expvar key/value dump |
Module-registered endpoints (via admin.api namespace)#
| Module ID | Pattern | Methods | Purpose |
|---|---|---|---|
admin.api.load | /load | POST | Load a full config (JSON body) |
admin.api.load | /adapt | POST | Adapt config from non-JSON format (returns JSON) |
admin.api.metrics | /metrics | GET | Prometheus metrics exposition |
admin.api.pki | /pki/ca/<id> | GET | PKI CA info (roots, intermediates) |
admin.api.pki | /pki/cas | GET | List all configured CAs |
admin.api.reverse_proxy | /reverse_proxy/upstreams | GET | Live upstream health status |
Extension point: Any module registered in the admin.api namespace that implements the AdminRouter interface (method Routes() []AdminRoute) gets its routes added to the admin mux at startup. This allows third-party modules to expose admin endpoints without modifying core code.
CLI#
- Framework:
github.com/spf13/cobrawith a thin wrapper (caddycmd.Commandstruct andRegisterCommand()function) - Entry point:
cmd/caddy/main.go→caddycmd.Main()→ cobra root command dispatch
Command structure#
| Command | Flags | Purpose |
|---|---|---|
caddy run | --config, --adapter, --envfile, --environ, --resume, --watch, --pidfile | Start Caddy in foreground (daemon mode) |
caddy start | --config, --adapter, --envfile, --watch, --pidfile | Start Caddy in background and return |
caddy stop | --config, --adapter, --address | Gracefully stop via admin API /stop |
caddy reload | --config, --adapter, --address, --force | POST new config to running instance via admin API /load |
caddy adapt | --config, --adapter, --pretty, --validate, --envfile | Convert config to Caddy JSON; outputs to stdout |
caddy validate | --config, --adapter, --envfile | Provision config (dry-run) to check for errors |
caddy fmt | --config, --overwrite, --diff | Format Caddyfile |
caddy list-modules | --packages, --versions, --skip-standard, --json | List all registered modules |
caddy build-info | — | Print Go build metadata |
caddy version | — | Print version string |
caddy environ | --envfile | Print environment variables |
caddy storage export | --config, --output | Export TLS/storage as tarball |
caddy storage import | --config, --input | Import storage tarball |
caddy upgrade | --keep-backup | Download updated binary (EXPERIMENTAL) |
caddy add-package | --keep-backup | Add plugin packages to binary (EXPERIMENTAL) |
caddy remove-package | --keep-backup | Remove packages from binary (EXPERIMENTAL) |
caddy manpage | --directory | Generate man pages (section 8) |
caddy completion | bash|zsh|fish|powershell | Shell completion scripts |
Flag patterns#
- Global flags: None — all flags are per-command.
- Config selection:
--config(path) +--adapter(adapter name) appear on most commands. - Address override:
--addresson commands that contact the admin API (stop, reload) to handle non-default admin listen addresses. - Env injection:
--envfilepre-loadsKEY=VALUEpairs before config parsing; available on run/start/validate/adapt/environ. - Extension point:
RegisterCommand(cmd Command)incmd/commands.goallows third-party plugins to add new CLI subcommands frominit()— same pattern as module registration.Command.CobraFuncgives access to the raw*cobra.Commandfor full cobra feature support.
Plugin / Extension System#
This is Caddy’s primary extensibility surface. Everything in Caddy is a module.
Core mechanism#
caddy.RegisterModule(m Module) // called from init()
caddy.GetModule(id string) (ModuleInfo, error)
caddy.GetModules(namespace string) []ModuleInfoA module implements the Module interface:
type Module interface {
CaddyModule() ModuleInfo // returns ID + constructor
}ModuleInfo.ID is a dotted namespace string (e.g. http.handlers.reverse_proxy). The namespace prefix determines where in the config JSON tree the module can appear, and which parent module will load it.
Extension namespaces#
| Namespace | Interface to implement | Purpose |
|---|---|---|
http.handlers.* | caddyhttp.MiddlewareHandler | HTTP request handlers (middleware) |
http.matchers.* | caddyhttp.RequestMatcherWithError | HTTP route matchers |
http.encoders.* | (encoding module) | Response body encoders (gzip, zstd) |
http.authentication.providers.* | (auth provider) | HTTP Basic/bearer auth providers |
http.authentication.hashes.* | (hash module) | Password hashing algorithms |
http.ip_sources.* | (IP source module) | Client IP extraction strategies |
http.precompressed.* | (precompressed module) | Pre-compressed file handling |
http.reverse_proxy.* | (load balancer / health check) | Reverse proxy sub-components |
tls.certificates.* | caddytls.CertificateLoader | TLS certificate sources |
tls.stek.* | caddytls.SessionTicketService | Session ticket key providers |
tls.client_auth.* | (client auth module) | mTLS client auth verifiers |
caddy.storage.* | certmagic.Storage | Storage backends for certs/data |
caddy.logging.encoders.* | caddy.LogEncoder | Log format encoders |
caddy.logging.writers.* | caddy.WriterOpener | Log output destinations |
caddy.listeners.* | caddy.ListenerWrapper | Network listener wrappers |
caddy.filesystems | fs.FS | Filesystem abstractions |
caddy.config_loaders.* | caddy.ConfigLoader | Runtime config sources (e.g. HTTP loader) |
caddy.network_proxy.* | (network proxy module) | Network-level proxy control |
admin.api.* | caddy.AdminRouter | Admin HTTP API extensions |
events.* | caddyevents.EventHandler | Event bus subscribers |
Caddyfile directive registration#
Modules that want Caddyfile support register parsers:
// For directives that produce route config values:
httpcaddyfile.RegisterDirective(dir string, fn UnmarshalFunc)
// For directives that produce a MiddlewareHandler:
httpcaddyfile.RegisterHandlerDirective(dir string, fn UnmarshalHandlerFunc)
// For declaring directive ordering relative to other directives:
httpcaddyfile.RegisterDirectiveOrder(dir string, position Positional, relTo string)Built-in Caddyfile directives registered at init: bind, tls, fs, root, vars, redir, respond, abort, error, route, handle, handle_errors, invoke, log, skip_log, log_skip, log_name.
Standard modules bundled in caddy binary#
HTTP handlers (18): file_server, reverse_proxy, rewrite, static_response, error, headers, encode, templates, authentication, authorization (caddyauth), map, vars, push, request_body, intercept, invoke, tracing, log_append, metrics, acme_server, copy_response, copy_response_headers
HTTP matchers (13): host, path, path_regexp, method, header, header_regexp, query, remote_ip, client_ip, protocol, tls, expression, vars, vars_regexp, file, not
TLS: ACME (HTTP-01, TLS-ALPN-01, DNS-01), OCSP stapling, session ticket rotation (standardstek, distributedstek), PKI CA with embedded ACME server
Storage: file_system (default on-disk)
Logging: console, json, filter encoders; stdout, stderr, discard, file, net writers
Library API#
Caddy is designed to be recompiled with custom modules rather than imported as a library, but it does expose public Go APIs:
Core package (github.com/caddyserver/caddy/v2)#
Key public types and functions:
caddy.RegisterModule(Module)— register a module (called frominit())caddy.Load(rawCfg []byte, forceReload bool) error— programmatic config loadcaddy.Context— passed to modules duringProvision(ctx); providesctx.App(name),ctx.LoadModule(cfg, fieldName),ctx.Logger(),ctx.Filesystems()caddy.Module,caddy.ModuleInfo,caddy.ModuleID— module identity typescaddy.App(Start() / Stop() error) — app lifecyclecaddy.Provisioner(Provision(Context) error) — module setup hookcaddy.Validator(Validate() error) — config validation hookcaddy.CleanerUpper(Cleanup() error) — module teardown hook
caddyhttp package#
caddyhttp.MiddlewareHandler— primary interface for HTTP handler modulescaddyhttp.RequestMatcherWithError— interface for request matcher modulescaddyhttp.Handler,caddyhttp.HandlerFunc— simplified handler typescaddyhttp.Middleware—func(Handler) Handlertype aliascaddyhttp.GetVar(ctx, key)/caddyhttp.SetVar(ctx, key, val)— per-request variable store
API style#
The library API follows the module interface pattern: implement one or more lifecycle interfaces, call RegisterModule() in init(), import the package in a custom binary. There is no builder or fluent API for constructing Caddy configs in Go — the intended programmatic interface is the admin API over HTTP or JSON config construction.
Backward compatibility: Caddy uses semantic versioning (v2 module path). The Module interface and core registration functions are stable. Individual module JSON config schemas are treated as stable within a major version. The RequestMatcher interface is explicitly deprecated in favor of RequestMatcherWithError, showing the evolution path.