Environment variables
This is the full reference for self-hosted instances. Start with the small .env example in the Docker guide; add other settings only when you need them.
Production startup requires a secret, the Quipthread URL, allowed publisher origins, and a sign-in provider. Email sign-in also requires an SMTP host and sender address.
Required
Section titled “Required”| Variable | Default | Description |
|---|---|---|
JWT_SECRET |
— | Required. Secret key used to sign session tokens. Generate with openssl rand -hex 32. |
Server
Section titled “Server”| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
TCP port the HTTP server listens on. |
BASE_URL |
http://localhost:8080 |
Public origin of Quipthread, such as https://comments.example.com. OAuth callbacks append /auth/github/callback or /auth/google/callback; do not put that path in BASE_URL. |
TRUST_PROXY |
false |
Trust forwarded client IP headers. Set to true behind Caddy or another trusted proxy, and prevent direct access to the app port. |
LOG_FORMAT |
text | Set to json for structured logs. |
LOG_LEVEL |
info | Set to debug for debug logs. |
Database
Section titled “Database”| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
./data/comments.db |
Path to the local SQLite database file. Docker Compose defaults to /data/db.sqlite in its persistent volume. Self-hosted mode rejects remote libsql://, http://, and https:// URLs before opening a driver. |
Auth — OAuth
Section titled “Auth — OAuth”| Variable | Default | Description |
|---|---|---|
GITHUB_CLIENT_ID |
— | GitHub OAuth app client ID. |
GITHUB_CLIENT_SECRET |
— | GitHub OAuth app client secret. |
GOOGLE_CLIENT_ID |
— | Google OAuth client ID. |
GOOGLE_CLIENT_SECRET |
— | Google OAuth client secret. |
See OAuth Setup for how to create these credentials.
Auth — Email
Section titled “Auth — Email”| Variable | Default | Description |
|---|---|---|
EMAIL_AUTH_ENABLED |
false |
Set to true to enable email+password registration and login. |
SMTP_HOST |
— | SMTP server hostname. |
SMTP_PORT |
587 |
SMTP server port. |
SMTP_USER |
— | SMTP authentication username. |
SMTP_PASS |
— | SMTP authentication password. |
SMTP_FROM |
— | Sender address for all outgoing email. |
See Email Authentication for details.
| Variable | Default | Description |
|---|---|---|
ALLOWED_ORIGINS |
— | Required in production. Comma-separated publisher origins, such as https://example.com,https://www.example.com. Include scheme and port where needed; paths and wildcards are rejected. BASE_URL is accepted separately for dashboard requests. |
Rate limiting
Section titled “Rate limiting”| Variable | Default | Description |
|---|---|---|
RATE_LIMIT_COMMENTS |
5/10m |
Rate limit for comment submissions. Format: count/duration where duration uses Go time syntax (e.g. 10m, 1h). 5/10m means 5 requests per 10 minutes per IP. |
RATE_LIMIT_AUTH |
10/5m |
Rate limit for auth endpoints. Same format as above. |
Spam filtering
Section titled “Spam filtering”| Variable | Default | Description |
|---|---|---|
SPAM_MAX_LINKS |
3 |
Maximum number of links (hrefs or bare URLs) allowed in a comment before it is auto-rejected as spam. |
Notifications
Section titled “Notifications”Self-hosted builds support SMTP email notifications. Configure the SMTP_* settings above.
| Variable | Default | Description |
|---|---|---|
NOTIFY_BATCH_SIZE |
5 |
Number of pending comments to accumulate before sending a notification. |
NOTIFY_COOLDOWN_HOURS |
24 |
Minimum hours between notification sends. |
NOTIFY_EMAIL_TO |
— | Fallback notification recipient email address, used when the site owner has no email address on their account. |
See Notifications for delivery settings and channel availability.
Bot protection
Section titled “Bot protection”| Variable | Default | Description |
|---|---|---|
TURNSTILE_SITE_KEY |
— | Cloudflare Turnstile site key. Served to the embed widget to render the challenge. |
TURNSTILE_SECRET_KEY |
— | Cloudflare Turnstile secret key. Used for server-side token verification. |
Both variables must be set to enable Turnstile bot protection. Leave both unset to disable it.
Docker backups
Section titled “Docker backups”These variables are read by the Docker entrypoint, not by the Go backend:
| Variable | Default | Description |
|---|---|---|
LITESTREAM_REPLICA_URL |
— | Replica URL. A nonempty value enables restore-on-startup and continuous replication with the packaged Litestream v0.3.14. |
LITESTREAM_ACCESS_KEY_ID |
— | Access key for the replica bucket. |
LITESTREAM_SECRET_ACCESS_KEY |
— | Secret key for the replica bucket. |
See Backups and restore for setup and restore behavior.
Managed cloud settings
Section titled “Managed cloud settings”Self-hosted builds use local SQLite and do not include managed billing or tenant provisioning. Leave CLOUD_MODE unset or false; setting it to true does not convert a self-hosted image into the managed platform. Turso and Stripe credentials are not needed for self-hosting.
How configuration is loaded
Section titled “How configuration is loaded”Process environment variables take priority. The backend then loads ../.env and .env without overwriting values already set. Docker Compose passes .env through env_file. Keep one configuration source per deployment to avoid conflicting values.