caddyserver

package module
v1.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 12, 2026 License: AGPL-3.0 Imports: 16 Imported by: 0

README

Swytch Redis server for Caddy

A Caddy app that embeds the full Swytch Redis server. Redis clients connect directly to its TCP or Unix socket listener. Commands, RESP handling, transactions, scripting, JSON, streams, blocking operations, ACLs, and pub/sub come from Swytch itself; this module adds Caddy configuration and lifecycle management. Compatibility is that of the pinned Swytch release, not a claim that every upstream Redis command is supported.

Build

Requires Go 1.27 or later. From this checkout:

xcaddy build --with github.com/swytchdb/caddy-server="$PWD"

Once published, omit the local replacement:

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

The module depends on released Swytch v1.4.0 and Engine v1.0.1; sibling checkouts are not required. Unlike caddy-storage, this app serves application data over Redis. It does not configure Caddy's certificate storage. The current sibling caddy-storage requires Engine v1.0.4, whose NewRuntime signature differs from Swytch v1.4.0's dependency. Combining those versions in one binary requires an upstream Swytch compatibility update first.

Caddyfile

swytch is a global option, outside HTTP site blocks:

{
    swytch {
        listen 127.0.0.1:6379
        password {env.REDIS_PASSWORD}
        max_memory 64mb
    }
}

For ACL authentication, replace password with acl_file /etc/swytch/users.acl. The file must already exist and parse successfully. For standalone operation, data is an in-memory cache; stopping the final app reference discards it.

DNS cluster configuration:

{
    swytch {
        listen 127.0.0.1:6379
        acl_file /etc/swytch/users.acl
        cluster_passphrase {env.SWYTCH_PASSPHRASE}
        join redis-peers.example.net
        cluster_port 7379
        cluster_advertise 10.0.0.5:7379
    }
}

Peers must use the same cluster passphrase. join follows Swytch's DNS discovery rules. Cluster startup uses Swytch's synchronous initialization, so joining peers or Cloud can delay Caddy startup.

For Swytch Cloud durability, use connection_secret {env.SWYTCH_CONNECTION_SECRET} instead of cluster_passphrase and join. Cloud supplies cluster identity and membership as well as durable storage across restarts and node loss, with zero-knowledge encryption. Ordinary peer replication alone does not provide that durability.

Options

JSON uses the same names under apps.swytch. Every Caddyfile option takes one value; booleans use true or false, and durations use strings such as 30s. String fields support Caddy placeholders, including {env.NAME}.

Option Default Purpose
listen 127.0.0.1:6379 TCP address; mutually exclusive with unix_socket
unix_socket empty Unix socket path; must not already exist at first start
unix_socket_mode 0700 Octal permissions in Caddyfile; numeric mode in JSON (448 for 0700)
password empty Password for the default user
acl_file empty Existing ACL file; mutually exclusive with password
max_memory 64mb Swytch memory limit; accepts sizes or percentages
compress false Compress values in effects
cluster_passphrase empty Enable peer replication
connection_secret empty Cloud identity and durability; excludes passphrase and join
join empty Discovery DNS name; requires passphrase
cluster_port 7379 Cluster QUIC port; independent of Redis listen port
cluster_advertise auto Advertised cluster host and port
max_connections 0 Concurrent client limit; zero is unlimited
read_timeout 0 Swytch read deadline; zero disables it
write_timeout 0 Swytch write deadline; zero disables it
tcp_keepalive 0 Keepalive period passed to Swytch
read_buffer_size 0 Read buffer bytes; zero uses Swytch's default
write_buffer_size 0 Write buffer bytes; zero uses Swytch's default
num_acceptors 0 Accept loops; zero uses Swytch's automatic selection
debug_logging false Swytch command logging
tls_cert_file empty PEM server certificate
tls_key_file empty PEM private key; required with certificate
tls_ca_file empty PEM CA bundle to require client certificates (mTLS)
tls_min_version 1.2 1.2 or 1.3

TLS uses Swytch's certificate-file support. Automatic Caddy certificate issuance and renewal are not wired to the Redis listener. Swytch's CLI entry point is not called, so CLI signal handling, process-wide thread settings, telemetry clients, and separate metrics/pprof HTTP listeners are not started.

Example JSON:

{
  "apps": {
    "swytch": {
      "listen": "127.0.0.1:6379",
      "password": "{env.REDIS_PASSWORD}",
      "max_memory": "64mb"
    }
  }
}

Lifecycle

Provisioning and caddy validate check options and authentication/TLS files without starting the Redis server or contacting peers. Caddy's Start phase creates the runtime and listener. An unchanged reload retains the same engine, connections, scripts, ACL state, and subscriptions. A changed configuration or changed ACL/TLS file content is rejected with a restart-required error, leaving the existing server running. Settings cannot be hot-swapped because Swytch owns process-wide Redis state. Only one server configuration per process is supported.

Final shutdown closes clients before stopping the cluster runtime. Failed starts release their resources; failed reloads cannot release another app's reference. An existing Unix socket path is never intentionally replaced; remove stale sockets before starting the process. Runtime ACL changes follow Swytch semantics; saving an ACL file changes its content and consequently requires restart on the next Caddy reload.

Development

go test ./...
go vet ./...

Tests exercise Caddyfile adaptation, validation, real RESP commands over a Unix socket, TLS, pub/sub, blocking commands, Caddy reload and rollback, shutdown/restart, and listener-start failure. They do not validate a multi-node cluster or Swytch Cloud deployment.

Licensed under AGPL-3.0-or-later, matching Swytch. See LICENSE.

Documentation

Overview

Package caddyserver embeds Swytch's Redis server as a Caddy app.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

type App struct {
	Config
	// contains filtered or unexported fields
}

App runs Swytch's Redis-compatible server inside Caddy. Redis clients connect directly to a TCP or Unix socket listener. Swytch supplies command execution, transactions, scripting, JSON, streams, ACLs, and pub/sub; this app configures the server and manages its lifecycle. Command compatibility follows the Swytch release included in the build.

Configure the module at apps.swytch in JSON, or with the swytch global option outside HTTP site blocks in a Caddyfile:

{
	swytch {
		listen 127.0.0.1:6379
		password {env.REDIS_PASSWORD}
		max_memory 64mb
	}
}

Caddyfile option names match the JSON fields. Each option takes one value; booleans use true or false, and durations accept strings such as "30s". String fields support Caddy placeholders, including {env.NAME}, which are expanded during provisioning.

By default, Swytch runs as an in-memory standalone cache whose data is lost on shutdown. Set cluster_passphrase and join for DNS-discovered peer replication, or connection_secret for Swytch Cloud membership and durable, zero-knowledge encrypted storage. Peer replication alone does not provide Cloud's durability across restarts and node loss. Joining peers or Cloud can delay Caddy startup.

Only one Swytch server configuration is supported per Caddy process. Unchanged reloads preserve data, client connections, runtime ACL changes, scripts, and subscriptions. Changes to options or ACL/TLS file contents require a process restart; reloads with such changes are rejected while the existing server keeps running. Validation checks configuration and files without opening listeners or contacting peers.

func (App) CaddyModule

func (App) CaddyModule() caddy.ModuleInfo

CaddyModule returns the module information for the swytch app.

func (*App) Cleanup

func (a *App) Cleanup() error

Cleanup also handles a configuration abandoned after Start.

func (*App) Provision

func (a *App) Provision(_ caddy.Context) error

Provision validates without opening listeners, starting workers, or joining peers.

func (*App) Start

func (a *App) Start() error

Start claims the running server or starts it for the first config.

func (*App) Stop

func (a *App) Stop() error

Stop releases only this app's reference, including during reload rollback.

func (*App) UnmarshalCaddyfile

func (a *App) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile parses the swytch global option. Subdirective names match the JSON fields in Config, and each takes exactly one value. Duplicate options and nested blocks are rejected. See App for a Caddyfile example.

func (*App) Validate

func (a *App) Validate() error

Validate checks configuration and authentication/TLS files without network I/O.

type Config

type Config struct {
	// TCP address for Redis clients, in host:port form. The port must be
	// between 1 and 65535. Defaults to "127.0.0.1:6379" when neither listen
	// nor unix_socket is set. Mutually exclusive with unix_socket.
	Listen string `json:"listen,omitempty"`

	// Unix socket path for Redis clients, instead of a TCP listener. The path
	// must not already exist at first start; remove stale sockets beforehand.
	// Mutually exclusive with listen. Disabled by default.
	UnixSocket string `json:"unix_socket,omitempty"`

	// Permission bits for the Unix socket. Zero or omitted uses 0700.
	// Use octal in the Caddyfile (0700) and a decimal JSON number (448).
	// Only permission bits through 0777 (511 in JSON) are accepted.
	UnixSocketMode uint32 `json:"unix_socket_mode,omitempty"`

	// Password required by the default Redis user. Mutually exclusive with
	// acl_file. When both are empty, clients can connect without authentication.
	// Supports placeholders such as {env.REDIS_PASSWORD}.
	Password string `json:"password,omitempty"`

	// Path to an existing Redis ACL file defining users, passwords, and
	// permissions. The file must load successfully during validation.
	// Mutually exclusive with password. Empty disables ACL file loading.
	ACLFile string `json:"acl_file,omitempty"`

	// Timeout for reading Redis commands, for example "30s". Zero or omitted
	// disables the read timeout. Must not be negative.
	ReadTimeout caddy.Duration `json:"read_timeout,omitempty"`

	// Timeout for writing Redis responses, for example "30s". Zero or omitted
	// disables the write timeout. Must not be negative.
	WriteTimeout caddy.Duration `json:"write_timeout,omitempty"`

	// Maximum number of concurrent Redis client connections. Zero or omitted
	// allows unlimited connections. Must not be negative.
	MaxConnections int `json:"max_connections,omitempty"`

	// Enable Swytch's debug-level Redis command logging. Defaults to false.
	DebugLogging bool `json:"debug_logging,omitempty"`

	// TCP keepalive period passed to Swytch, for example "30s". Zero or omitted
	// leaves the listener's keepalive defaults unchanged. Must not be negative.
	TCPKeepAlive caddy.Duration `json:"tcp_keepalive,omitempty"`

	// Read buffer size per Redis client connection, in bytes. Zero or omitted
	// uses Swytch's default. Must not be negative.
	ReadBufferSize int `json:"read_buffer_size,omitempty"`

	// Write buffer size per Redis client connection, in bytes. Zero or omitted
	// uses Swytch's default. Must not be negative.
	WriteBufferSize int `json:"write_buffer_size,omitempty"`

	// Number of parallel TCP accept loops. Zero or omitted uses the CPU count
	// on platforms supporting SO_REUSEPORT; other platforms use one acceptor.
	// Does not apply to Unix sockets. Must not be negative.
	NumAcceptors int `json:"num_acceptors,omitempty"`

	// Path to a PEM server certificate enabling TLS for Redis clients.
	// Requires tls_key_file. Empty disables TLS. Certificates are loaded from
	// files; Caddy's automatic certificate issuance and renewal are not used.
	TLSCertFile string `json:"tls_cert_file,omitempty"`

	// Path to the PEM private key matching tls_cert_file. The certificate and
	// key must be configured together and load successfully during validation.
	TLSKeyFile string `json:"tls_key_file,omitempty"`

	// Path to a PEM CA bundle used to require and verify Redis client
	// certificates (mutual TLS). Requires tls_cert_file and tls_key_file.
	// Empty disables client certificate authentication.
	TLSCAFile string `json:"tls_ca_file,omitempty"`

	// Minimum TLS version for Redis clients: "1.2" or "1.3". Defaults to "1.2".
	// Only takes effect when tls_cert_file and tls_key_file enable TLS.
	TLSMinVersion string `json:"tls_min_version,omitempty"`

	// Swytch memory limit, as a byte count, a size such as "64mb" or "1gb",
	// or a whole-number percentage such as "50%" (1 through 100).
	// Size suffixes are case-insensitive and use powers of 1024.
	// Defaults to "64mb". This configures Swytch, not a process-wide Caddy limit.
	MaxMemory string `json:"max_memory,omitempty"`

	// Store values compressed in Swytch's effects engine, decompressing them
	// on read to trade CPU work for lower memory use. Defaults to false.
	// Peers with different compression settings can interoperate.
	Compress bool `json:"compress,omitempty"`

	// Shared passphrase enabling peer replication and deriving the cluster's
	// mutual TLS identity. Peers must use the same passphrase. Use join for DNS
	// peer discovery. Mutually exclusive with connection_secret.
	// Empty, with no connection_secret, selects standalone operation.
	ClusterPassphrase string `json:"cluster_passphrase,omitempty"`

	// Swytch Cloud connection secret providing cluster identity, membership,
	// and durable storage across restarts and node loss with zero-knowledge
	// encryption. Mutually exclusive with cluster_passphrase and join.
	// Empty disables Cloud. Supports {env.SWYTCH_CONNECTION_SECRET}.
	ConnectionSecret string `json:"connection_secret,omitempty"`

	// DNS name to resolve for peer discovery using Swytch's discovery rules.
	// Requires cluster_passphrase and is mutually exclusive with
	// connection_secret. Empty disables DNS peer discovery.
	Join string `json:"join,omitempty"`

	// QUIC port for cluster traffic when peer replication or Cloud is enabled.
	// Defaults to 7379, independently of the Redis client listen port.
	// Must be between 1 and 65535.
	ClusterPort int `json:"cluster_port,omitempty"`

	// Cluster host:port advertised to peers, for example "10.0.0.5:7379".
	// Empty lets Swytch detect the address automatically. Only used when
	// peer replication or Cloud is enabled.
	ClusterAdvertise string `json:"cluster_advertise,omitempty"`
}

Config configures the Redis listener, authentication, TLS, memory use, and optional Swytch peer replication or Cloud storage. Its fields are embedded directly in the swytch app's JSON object.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL