Learning Caddy - Architecture & Core Concepts
Episode 2 of 31

Learning Caddy - Architecture & Core Concepts

This episode dissects Caddy's architecture: the HTTP server core, the module system, the admin API, and the storage layer. You'll also learn the request flow, Caddyfile structure, the concepts of site address, directive, matcher, and handler, plus the four configuration methods.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

You now know why Caddy exists. Episode 2 takes you one level deeper: understanding the architecture and core concepts that underpin all configuration. Once you understand that a directive is an action and a matcher is a criterion, reading someone else's Caddyfile will feel like reading a language you already know.

Caddy is built as a collection of modules running on top of a small core. This architecture makes Caddy easy to extend — almost every feature, from TLS to reverse proxy, is a module that can be replaced or added. This understanding is also what lets you use the caddy list-modules feature with confidence.

Episode 2 covers the architecture components, Caddyfile structure, the request flow, and the four configuration methods available. You don't need to memorize every term — what matters is understanding the mindset.

Caddy Architecture Components

Server Core and the Module System

Caddy's architecture consists of several layers:

  • HTTP server core: the engine that accepts connections and executes handlers.
  • TLS management: the module that handles certificates and the ACME protocol.
  • Reverse proxy engine: the module that forwards requests to backends.
  • Module system: the framework that turns every feature into a loadable module.
  • Admin API: local HTTP endpoints for changing configuration at runtime.
  • Storage layer: where certificates and ACME data are stored.

Every module has a type and a name. When you run caddy list-modules, that long list is every module compiled into your binary.

Storage Layer: Where Certificates Live

Caddy stores certificates and keys in storage, by default at $XDG_DATA_HOME/caddy on Linux. This storage concept matters because:

  • Storage determines where ACME certificates are placed.
  • It can be moved to Redis, S3, or a networked filesystem for clusters.
  • One shared storage can be used by many Caddy instances without conflicts.

We'll dig into storage in depth in episodes 7 and 10.

Caddyfile Structure

Site Blocks, Directives, and Global Options

The Caddyfile is made up of global options at the top and site blocks below them. A site block opens with the site address and contains directives inside:

Basic Caddyfile structure
example.com {
    root * /var/www
    encode gzip
    file_server
}
  • Site address: example.com determines which domain is served.
  • Directive: root, encode, file_server are actions executed in order.
  • Global options: options like email and admin are written outside site blocks.

Matchers, Named Matchers, and Snippets

Directives can be constrained with matchers — criteria that decide which requests get processed. There are two forms:

  • Inline matcher: written directly after the directive, e.g. @api { path /api/* } or header Content-Type application/json.
  • Named matcher: given a name with a @ prefix, then reused across several directives.

A snippet is a named block that can be inserted into many sites — analogous to a macro or include:

Snippet and named matcher
(common) {
    encode gzip zstd
    header {
        X-Frame-Options DENY
    }
}
 
site-a.example.com {
    import common
    root * /var/www/a
    file_server
}

Snippets are marked with parentheses in their name and invoked with the import directive. This keeps repeated configuration DRY.

The Request Flow in Caddy

From Listener to Response

When a request arrives, Caddy runs a structured flow:

  1. The request arrives at the listener (port 80 or 443).
  2. TLS is handled first if it's HTTPS.
  3. Matchers are evaluated to determine which directives apply.
  4. Handlers execute in order, following the directive order.
  5. If a reverse proxy is configured, the request is forwarded to the backend.
  6. The response is sent back to the client.

Directive order matters: for example, redir should be written before file_server so the redirect catches the request first. We'll discuss ordering and placement in episodes 4 and 13.

Concepts: Address, Directive, Matcher, Handler, Module

  • Site address: a domain-and-port combination, e.g. localhost:8080.
  • Directive: the human-friendly way to write configuration.
  • Matcher: request criteria, such as path, method, or header.
  • Handler: the object that actually processes the request.
  • Module: the extensibility unit that wraps handlers, matchers, and other features.

A single directive can map to one or more handlers, and a single handler can be used by many directives.

Caddy Configuration Methods

Four Ways to Configure

Caddy accepts configuration through four paths:

  • Caddyfile: a human-friendly format converted to JSON by an adapter.
  • JSON: the native format Caddy understands directly.
  • Admin API: the :2019 endpoint for loading and changing configuration at runtime.
  • Adapters: transformations for other formats, such as adding custom adapters.

The caddy adapt command shows the JSON produced from a Caddyfile:

Convert a Caddyfile to JSON
caddy adapt --config Caddyfile

And JSON can be loaded directly through the admin API:

Load JSON config via the admin API
curl -X POST -H 'Content-Type: application/json' \
     -d @config.json http://localhost:2019/load

curl -X POST ... -d @config.json is how you load dynamic configuration. We'll dissect this admin API thoroughly in episode 23.

Conclusion

Episode 2 introduced Caddy's conceptual foundation: a modular architecture with an HTTP core, TLS management, a reverse proxy engine, the admin API, and a storage layer; the Caddyfile structure with site blocks, directives, matchers, named matchers, and snippets; the request flow from listener to response; and the four configuration methods.

Key takeaways:

  • Every Caddy feature is a module; the core only provides the framework.
  • The Caddyfile consists of global options and site blocks.
  • Matchers constrain directives; snippets make configuration reusable.
  • Directive order determines the execution result.
  • Configuration can be a Caddyfile, JSON, or loaded via the admin API.
  • The storage layer holds certificates and can be shared across instances.

In the next episode, episode 3, we'll install Caddy completely — from official package managers, binary downloads, Docker, to building from source — and run a first run to make sure everything works before diving into Caddyfile material.