Skip to main content
JSON is Caddy’s native configuration format. While the Caddyfile is more human-friendly, JSON provides complete control over Caddy’s configuration with explicit structure and validation.

Overview

Every configuration in Caddy is ultimately JSON. When you use a Caddyfile, it’s converted (adapted) to JSON before being used. The JSON format is expressed natively as a Go struct and can be manipulated through Caddy’s admin API.
Caddy config is expressed natively as a JSON document. If you prefer not to work with JSON directly, there are many config adapters available that can convert various inputs into Caddy JSON.

Root Config Structure

From caddy.go:46-95, the top-level configuration structure:

Top-Level Fields

Admin

Configures Caddy’s API endpoint from admin.go:67-125:
Disabling the admin endpoint makes runtime config changes impossible. Use with caution in production.

Logging

From logging.go:41-81, logging configuration:

Storage

Defines where Caddy stores TLS certificates and other assets:
The default storage module is file_system with a platform-specific default path. On Linux, this is typically $HOME/.local/share/caddy or /var/lib/caddy.

Apps

Apps are the modules that Caddy runs. The app module name is the key:

Module System

Caddy uses a modular architecture. From the source documentation:
Fields which have a json.RawMessage type and which appear as dots (•••) in the online docs can be fulfilled by modules in a certain module namespace.
Modules are specified in two ways:

Inline Key

Module Map

Duration Values

From caddy.go:855-906, durations can be integers (nanoseconds) or strings:

Working with JSON Configs

Loading Configuration

From caddy.go:104-143, load configuration via the API or programmatically:

Validating Configuration

From caddy.go:735-743:

Adapting from Caddyfile

Convert Caddyfile to JSON (caddyconfig/caddyfile/adapter.go:31-64):

HTTP App Configuration

The HTTP app is the most commonly used:

TLS Configuration

Reverse Proxy Example

Complete reverse proxy configuration:

Configuration Management

Auto-Save

From caddy.go:362-384, Caddy can persist configurations:
When enabled, Caddy automatically saves the active config to disk at $XDG_CONFIG_HOME/caddy/autosave.json. Load it on restart with caddy run --resume.

Dynamic Config Loading

From admin.go:127-150, load config from external sources:
A delay (load_delay) is required if dynamically-loaded configs also load other configs, to prevent tight loops.

API Operations

GET Current Config

POST New Config

PATCH Partial Update

DELETE Config Path

Best Practices

Convention: All config settings are optional. Caddy provides good, documented default values. Required parameters are clearly documented.
  1. Validate before deploying: Use caddy validate to check configs
  2. Start minimal: Begin with basic config and add complexity as needed
  3. Use modules: Leverage Caddy’s module system for extensibility
  4. Version control: Keep JSON configs in git for change tracking
  5. Document modules: Add comments in a separate doc file (JSON doesn’t support comments)
  6. Use the adapter: For complex configs, write in Caddyfile and adapt to JSON

Common Patterns

Multi-Site Hosting

Static File Server

Error Responses

Configuration errors include detailed information:

See Also