Skip to main content
Swytch Documentation
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Caddy Storage

Swytch ships a Caddy storage module. A pool of Caddy instances configured with it becomes a Swytch cluster: TLS certificates, ACME account state, and OCSP staples replicate peer-to-peer, and ACME issuance locks are coordinated through Swytch’s serializable transactional path.

Running Caddy in high availability normally requires an external KV store (Consul, Redis, S3 + DynamoDB) for certificate storage and issuance locking. With this module there is no external dependency: the Swytch effects engine is embedded in the Caddy process itself.

Building

The module is published as a separate Go module, github.com/swytchdb/swytch/caddy, to keep its dependency tree off the Swytch core. Build a Caddy binary with xcaddy:

xcaddy build --with github.com/swytchdb/swytch/caddy

Configuration

Caddyfile

{
    storage swytch {
        cluster_passphrase <secret>     # empty = single-node (no replication)
        connection_secret <secret>      # Swytch Cloud durability; excludes cluster_passphrase + join
        join <dns-name>                 # peers resolve via DNS; optional
        cluster_port <num>              # QUIC port; default 7380/UDP
        cluster_advertise <addr:port>   # this node's reachable address; auto-detect if empty
        key_prefix __caddy:             # default; must live under __caddy:
        lock_ttl 30s                    # ACME issuance lock TTL; default 30s
    }
}

:80 {
    # ... your site config
}

Point every Caddy instance at the same join DNS name (which must resolve to at least one peer’s cluster_advertise address) and they form a cluster. cluster_passphrase must match across every node; generate one with swytch gen-passphrase.

JSON

The field names are the JSON equivalents of the Caddyfile keywords:

{
  "storage": {
    "module": "swytch",
    "cluster_passphrase": "...",
    "connection_secret": "...",
    "join": "...",
    "cluster_port": 7380,
    "cluster_advertise": "10.0.0.1:7380",
    "key_prefix": "__caddy:",
    "lock_ttl": "30s"
  }
}

Swytch Cloud

Setting connection_secret enables Swytch Cloud durability and is a self-contained cluster identity: the cluster passphrase derives from it and peers come from the Cloud roster, so it is mutually exclusive with cluster_passphrase and join. TLS state still replicates peer-to-peer; Cloud is the backstop that rehydrates keys evicted from every live peer. Generate the secret with swytch gen-passphrase --cloud.

Semantics

  • Certificate storage uses the reserved __caddy: key namespace, kept separate from Swytch’s internal keys so certificate data participates in normal eviction.
  • ACME issuance locks are acquired through serializable transactions with a TTL (lock_ttl). If the holder dies without unlocking, the lock expires and another node acquires it; releases wake waiting nodes through replication callbacks rather than polling.
  • Single-node mode (cluster_passphrase empty) binds no QUIC port and runs no peer discovery. It is useful for local development.

Lifecycle

The embedded engine is a process-wide singleton and Caddy reloads reuse it. Changing cluster_passphrase, connection_secret, join, cluster_port, cluster_advertise, or key_prefix at reload time is rejected; these are baked into the QUIC listener, TLS certificate SAN, or peer-discovery state at startup. Restart the process to change them. lock_ttl does take effect on the next reload.