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

Share TLS certificates across Caddy instances without an external database. Each Caddy process embeds a Swytch node for certificate state and ACME issuance locks.

Use this module for Caddy’s storage. For application Redis commands, use the Redis server app.

Building

The module is published as a separate Go module, github.com/swytchdb/caddy-storage, and depends on Swytch Engine. Build a Caddy binary with xcaddy:

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

Configuration

Caddyfile

{
    storage swytch {
        cluster_passphrase <secret>     # empty = single-node (no replication)
        join 10.0.0.1:7380              # a reachable peer's QUIC endpoint
        cluster_port 7380              # local QUIC listener; default 7380/UDP
        cluster_advertise 10.0.0.2:7380 # this instance's reachable endpoint
        key_prefix __caddy:             # default; must live under __caddy:
        lock_ttl 30s                    # ACME issuance lock TTL; default 30s
        data_dir /tmp/data              # location to store disk recovery files
    }
}

:80 {
    # ... your site config
}

Set join to a reachable peer’s ip:port and cluster_advertise to this instance’s own reachable ip:port. For the first instance on 10.0.0.1, use 10.0.0.1:7380 for both settings. Start it before the instance on 10.0.0.2 shown above. Allow UDP 7380 between the advertised endpoints. 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": "...",
        "join": "10.0.0.1:7380",
        "cluster_port": 7380,
        "cluster_advertise": "10.0.0.2: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.

Memory-only certificate state is lost if every holder stops or evicts it. Use Cloud when certificate state must survive full-cluster replacement; its uploads are asynchronous.

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.