Configuration
Weirling reads its settings from environment variables (or .env).
./scripts/init_env.sh writes a .env with fresh secrets; every variable,
with a comment, is in .env.example .
The tables below cover the ones you are most likely to change.
Settings marked Setup screen can also be changed by the instance owner at
/admin/setup. A value set in the environment always wins.
Core
Variable
Default
What it does
APP_ENV
production
production or development. Production refuses weak secrets and requires secure cookies.
DEPLOYMENT_MODE
selfhost
selfhost: one tenant, no quotas, full text in the reader. hosted: plans, quotas, abuse limits.
SECRET_KEY
required
Signs sessions. Generated by init_env.sh.
REFRESH_SECRET_KEY
SECRET_KEY
Optional separate secret for refresh tokens.
SECRETS_ENCRYPTION_KEY
empty
Encrypts secrets saved from the setup screen. Without it, the screen can't store them.
METRICS_TOKEN
required
Operator token for /metrics and /api/v1/metrics/* (X-Metrics-Token). The instance owner can read the Ingestion page without it.
REGISTRATION_MODE
closed (self-host)
closed, invite (codes in REGISTRATION_INVITE_CODES) or open. The first account always becomes the owner. Setup screen
EMAIL_VERIFICATION
auto
auto (required on hosted, off on self-host), required or off.
FRONTEND_URL
http://localhost:3001
The web app's address: CORS and links in emails.
CORS_EXTRA_ORIGINS
empty
More allowed origins, comma-separated (for example the www. host).
PUBLIC_API_URL
http://localhost:8000
The API's public address, used in unsubscribe links.
COOKIE_DOMAIN
host only
Set .example.com when the API and the app are on different subdomains.
COOKIE_SECURE
auto
HTTPS-only cookies, except on localhost or LAN over HTTP.
Database and Redis
Variable
Default
What it does
DATABASE_URL
postgresql+asyncpg://readprism:readprism@db:5432/readprism
Postgres with pgvector. A plain postgres:// URL (Railway, Render, Heroku) is accepted.
DATABASE_SYNC_URL
derived from DATABASE_URL
Used by migrations.
AUTO_MIGRATE
true
Run migrations at start-up, under a lock, so several containers migrate once.
DB_POOL / DB_POOL_SIZE / DB_MAX_OVERFLOW
auto / 10 / 10
The API pools connections; workers don't (auto). Lower the sizes on small managed databases.
REDIS_URL
redis://redis:6379/0
Cache, rate limits, sessions.
CELERY_BROKER_URL
redis://redis:6379/1
Job queue.
CELERY_RESULT_BACKEND
redis://redis:6379/2
Job results.
The compose Redis keeps an append-only log on the redis_data volume, so a
restart keeps sessions and pending sign-in links. make backup snapshots it.
Summaries (LLM)
Variable
Default
What it does
LLM_API_KEY
empty
Any OpenAI-compatible key. Without one, summaries are extracts and nothing is sent anywhere. Setup screen
LLM_BASE_URL
https://api.groq.com/openai/v1
Groq, OpenAI, OpenRouter, a local Ollama. Setup screen
LLM_MODEL_PRIMARY
openai/gpt-oss-120b
Story synthesis and interest expansion. Setup screen
LLM_MODEL_FAST
openai/gpt-oss-20b
Item summaries and topics. Setup screen
LLM_MODEL_SUMMARY, _TOPICS, _SYNTHESIS, _INTERESTS
empty
Override the model for one task (which model does what ).
LLM_SUMMARIZE
lazy
lazy: only items that reach a digest or the reader. all: every item.
OPENAI_FALLBACK_ENABLED
false
Fall back to OPENAI_API_KEY / OPENAI_MODEL when the main provider fails.
GROQ_API_KEY is still read in 0.3.x and will be removed; use LLM_API_KEY.
Embeddings and ranking
Variable
Default
What it does
EMBEDDING_MODEL
all-MiniLM-L6-v2
Local sentence-transformers model, or hash (no PyTorch; weaker matching). See switching models .
EMBEDDING_DEVICE
cpu
cpu or cuda.
OMP_NUM_THREADS / TORCH_NUM_THREADS
container CPUs
PyTorch threads. By default they follow the container's CPU quota.
SERENDIPITY_DEFAULT_PERCENTAGE
15
Share of each digest kept for discovery.
COLD_START_COLLABORATIVE_ENABLED
true
"Popular with readers" picks, from 100 active readers and only for items 20 readers finished.
RANKER_VERSION
2
Ranking engine version.
Email
Variable
Default
What it does
EMAIL_PROVIDER
auto
auto: Resend when RESEND_API_KEY is set, otherwise SMTP. Or force smtp / resend.
RESEND_API_KEY
empty
A sending-only Resend key. Use it where outbound SMTP is blocked (Railway Hobby and many clouds).
SMTP_HOST / SMTP_PORT
empty / 587
Port 587 uses STARTTLS, 465 uses TLS. Setup screen
SMTP_USER / SMTP_PASSWORD
empty
The mailbox login. Email is skipped while no provider is configured. Setup screen
FROM_EMAIL / FROM_NAME
SMTP_USER / Weirling
The sender. With Resend it must be on a verified domain.
REPLY_TO_EMAIL
empty
Where replies go, for example support@.
SUPPORT_EMAIL
grievance contact
Help address shown in the app.
GRIEVANCE_CONTACT_EMAIL
empty
Privacy and takedown contact, shown on /contact.
EMAIL_PHYSICAL_ADDRESS
empty
Postal address in the email footer. Set it before sending to US readers.
DNS for deliverability (SPF, DKIM, DMARC) is in Install & run .
Hosted service
Variable
Default
What it does
BILLING_PROVIDER
empty
lemonsqueezy, paddle or razorpay. While empty, trials never run out: no trial emails, pausing or deletion.
BILLING_WEBHOOK_SECRET / BILLING_API_KEY
empty
Webhook signature secret and API key for the provider.
BILLING_TRIAL_DAYS
30
Trial length once billing is on.
HOSTED_PAUSED_DELETE_DAYS
30
Days a paused account is kept before deletion (0 never deletes).
READER_FULL_TEXT
auto
auto: hosted shows only text the publisher put in its feed; self-host shows everything. Or all / feed_only.
HOSTED_FETCH_BUDGET_PER_HOUR
300
Fetches one account may cause per hour.
HOSTED_HOST_POLLS_PER_HOUR
120
Polls of any one website per hour, across all accounts.
HOSTED_MAX_SOURCES_PER_HOST
10
Feeds one account may follow on the same website.
SIGNUP_PER_DOMAIN_PER_HOUR
10
Sign-ups per email domain per hour.
TELEMETRY_RAW_RETENTION_DAYS
90
Raw reading telemetry kept before it is aggregated (0 keeps it).
CONTENT_FULL_TEXT_RETENTION_DAYS
90
Stored article text is cut to an excerpt after this many days.
More on plans, quotas and the account lifecycle: Hosted service .
Fetching
Variable
Default
What it does
SSRF_PROTECTION_ENABLED
true
Every fetch resolves the host, refuses private addresses and connects to the checked IP.
BROWSERLESS_URL
http://browserless:3000
Headless Chrome for pages that need JavaScript (full profile).
RSSHUB_BASE_URL
empty
RSSHub bridge for platforms without feeds (bridge profile).