Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/fuomag9/caddy-proxy-manager/llms.txt

Use this file to discover all available pages before exploring further.

Caddy Proxy Manager is configured entirely through environment variables passed to the Docker Compose stack. This page lists every supported variable, explains the available Docker Compose profiles for optional services, and documents the volumes used to persist data across container restarts.

Required variables

These variables must be set before starting the stack. The web container will refuse to start if SESSION_SECRET, ADMIN_USERNAME, or ADMIN_PASSWORD are missing or empty.
SESSION_SECRET
string
required
Secret key used to encrypt session cookies. Must be at least 32 characters in production.Generate a suitable value with:
openssl rand -base64 32
ADMIN_USERNAME
string
required
Username for the initial admin account created on first start. Defaults to admin in the example file.
ADMIN_PASSWORD
string
required
Password for the initial admin account. In production, must be 12 or more characters with at least one uppercase letter, one lowercase letter, one number, and one special character.Default admin credentials are only permitted when NODE_ENV=development.

Application settings

BASE_URL
string
default:"http://localhost:3000"
Public URL where users access the dashboard, without a trailing slash. Required for OAuth — must exactly match the redirect URI registered in your OAuth provider.Examples: http://localhost:3000, https://caddy-manager.example.com
CADDY_API_URL
string
default:"http://caddy:2019"
Internal URL of Caddy’s Admin API. The default (http://caddy:2019) works correctly inside the Docker Compose network. Change this only if you run Caddy outside the default stack.
DATABASE_URL
string
default:"file:/app/data/caddy-proxy-manager.db"
SQLite connection URL. The database file is stored in the caddy-manager-data volume at /app/data inside the container. Changing this path is not recommended unless you are using a custom volume mount.
CERTS_DIRECTORY
string
default:"./data/certs"
Directory where manually imported certificate files are stored. This path is relative to the application working directory inside the container.

Authentication settings

LOGIN_MAX_ATTEMPTS
number
default:"5"
Maximum number of failed login attempts allowed within the LOGIN_WINDOW_MS window before the account is temporarily blocked.
LOGIN_WINDOW_MS
number
default:"300000"
Duration of the login rate-limit window in milliseconds. Default is 5 minutes (300,000 ms).
LOGIN_BLOCK_MS
number
default:"900000"
Duration of the login block in milliseconds after LOGIN_MAX_ATTEMPTS is exceeded. Default is 15 minutes (900,000 ms).
AUTH_TRUST_HOST
boolean
default:"false"
Trust the Host header for URL construction. Enable only when CPM is running behind a reverse proxy that rewrites the Host header to the correct public hostname.
AUTH_RATE_LIMIT_ENABLED
boolean
default:"true"
Enable Better Auth’s built-in rate limiting for all authentication endpoints.
AUTH_RATE_LIMIT_WINDOW
number
default:"60"
Better Auth rate-limit window in seconds.
AUTH_RATE_LIMIT_MAX
number
default:"5"
Maximum number of authentication requests allowed within AUTH_RATE_LIMIT_WINDOW seconds.

OAuth2/OIDC settings

OAUTH_ENABLED
boolean
default:"false"
Enable OAuth2/OIDC authentication. When true, an OAuth login button appears on the login page alongside the credential form.
OAUTH_PROVIDER_NAME
string
default:"OAuth2"
Display name for the OAuth provider shown on the login button (e.g. Authentik, Keycloak).
OAUTH_CLIENT_ID
string
OAuth2 client ID issued by your identity provider.
OAUTH_CLIENT_SECRET
string
OAuth2 client secret issued by your identity provider.
OAUTH_ISSUER
string
OIDC issuer URL used for automatic endpoint discovery. CPM fetches {OAUTH_ISSUER}/.well-known/openid-configuration to discover the authorization, token, and userinfo endpoints.Example: https://auth.example.com/application/o/caddy-proxy/
OAUTH_AUTHORIZATION_URL
string
Override the auto-discovered OAuth authorization endpoint. Leave empty to use OIDC discovery from OAUTH_ISSUER.
OAUTH_TOKEN_URL
string
Override the auto-discovered OAuth token endpoint. Leave empty to use OIDC discovery from OAUTH_ISSUER.
OAUTH_USERINFO_URL
string
Override the auto-discovered OAuth userinfo endpoint. Leave empty to use OIDC discovery from OAUTH_ISSUER.
OAUTH_ALLOW_AUTO_LINKING
boolean
default:"false"
Automatically link an OAuth identity to an existing CPM account with the same email address, even if the account has no password. Enable with caution — only if you trust your OAuth provider to verify email addresses.

Analytics (ClickHouse)

These variables are only relevant when the clickhouse Docker Compose profile is active.
CLICKHOUSE_URL
string
default:"http://clickhouse:8123"
ClickHouse HTTP endpoint. The default works inside the Docker Compose network. Change this if you use an external ClickHouse instance.
CLICKHOUSE_USER
string
default:"cpm"
ClickHouse username.
CLICKHOUSE_PASSWORD
string
ClickHouse password. Required when the clickhouse profile is active — the clickhouse container will not start without it.Generate a secure value with:
openssl rand -base64 32
CLICKHOUSE_DB
string
default:"analytics"
ClickHouse database name where traffic and WAF events are stored.

Instance sync

Instance sync allows a master CPM instance to push proxy host, certificate, access list, and settings configuration to one or more slave instances on every change. User accounts are not synced.
INSTANCE_MODE
string
default:"standalone"
Instance role. Accepted values: standalone, master, slave.
INSTANCE_SYNC_TOKEN
string
Bearer token that slave instances use to authenticate incoming sync requests from the master. Required on slave instances. Must be at least 32 characters.
INSTANCE_SLAVES
string
JSON array of slave instance descriptors. Required on the master. Each object has name, url, and token fields.Example:
[{"name":"replica","url":"https://replica.example.com","token":"<32-char-token>"}]
INSTANCE_SYNC_INTERVAL
number
default:"0"
Periodic sync interval in seconds. Set to 0 to disable periodic sync and rely only on change-triggered pushes.
INSTANCE_SYNC_ALLOW_HTTP
boolean
default:"false"
Allow sync over HTTP. Enable only for slave URLs on internal Docker networks. Use HTTPS slave URLs in production.

Docker Compose profiles

Profiles activate optional services without modifying the docker-compose.yml file. Set the COMPOSE_PROFILES variable in your .env file.
Starts the clickhouse container (ClickHouse latest-alpine image). Traffic events and WAF events are written to ClickHouse and retained for 90 days via TTL. The Analytics page in the dashboard is fully functional only when this profile is active.Requires CLICKHOUSE_PASSWORD to be set. The container will not start without it.
COMPOSE_PROFILES=clickhouse
CLICKHOUSE_PASSWORD=your-clickhouse-password
Starts the geoipupdate container (official MaxMind image). Downloads GeoLite2 Country, City, and ASN databases and refreshes them every 72 hours. The databases are stored in the geoip-data volume and are shared with the web and caddy containers.Required for geo blocking rules to function. Requires a free MaxMind account and license key.
COMPOSE_PROFILES=geoipupdate
GEOIPUPDATE_ACCOUNT_ID=your-account-id
GEOIPUPDATE_LICENSE_KEY=your-license-key
List multiple profiles as a comma-separated string to activate more than one optional service at the same time:
COMPOSE_PROFILES=clickhouse,geoipupdate
CLICKHOUSE_PASSWORD=your-clickhouse-password
GEOIPUPDATE_ACCOUNT_ID=your-account-id
GEOIPUPDATE_LICENSE_KEY=your-license-key

Volumes

All persistent data is stored in named Docker volumes. These volumes survive container restarts and upgrades.
VolumeMounted inStores
caddy-manager-dataweb, l4-port-managerSQLite database, imported certificate files, and application data
caddy-datacaddyCaddy’s ACME certificate cache and storage (Let’s Encrypt / ZeroSSL certs)
caddy-configcaddyCaddy runtime configuration state
caddy-logscaddy (write), web (read-only)Caddy access logs consumed by the analytics pipeline
geoip-dataweb (read-only), caddy (read-only), geoipupdate (write)MaxMind GeoLite2 Country, City, and ASN database files
clickhouse-dataclickhouseClickHouse analytics data: traffic events and WAF events with 90-day TTL
Back up caddy-manager-data and caddy-data regularly. caddy-manager-data contains your configuration database and caddy-data contains the ACME account keys and cached certificates.

Production security checklist

Generate SESSION_SECRET with openssl rand -base64 32 — do not use a short or guessable value.
Set ADMIN_PASSWORD to 12 or more characters with uppercase, lowercase, numbers, and special characters.
Set BASE_URL to your HTTPS public URL (e.g. https://caddy-manager.example.com), not http://localhost:3000.
Run chmod 600 .env to prevent other users on the host from reading your credentials.
Keep the Caddy Admin API (port 2019) on the internal Docker network only — do not expose it to the host.
Use HTTPS URLs for INSTANCE_SLAVES in multi-instance deployments. Only set INSTANCE_SYNC_ALLOW_HTTP=true on internal-only networks.
Generate CLICKHOUSE_PASSWORD with openssl rand -base64 32 if you enable the clickhouse profile.

Build docs developers (and LLMs) love