Skip to content

Configuration

Ember reads configuration from environment variables at startup. A handful of settings can also be changed at runtime via the admin UI and persist in the app_settings table.

Required env vars

VarDescription
EMBER_SESSION_KEYsecurecookie key, 32+ random bytes. Generate via openssl rand -base64 48.
EMBER_ADMIN_PASSWORDFirst-run admin password. Used only when the users table is empty; change via Settings → Profile after first login.

Optional env vars

VarDefaultNotes
EMBER_ADDR:8080Bind address.
EMBER_DB_PATH/data/ember.dbSQLite file path.
EMBER_ADMIN_USERadminFirst-run admin username.
EMBER_OLLAMA_URLhttp://ollama:11434Ollama API endpoint.
EMBER_OLLAMA_MODELqwen2.5:0.5bInitial active model. The admin UI can swap to any pulled model live.
EMBER_DISABLE_SUMMARIES0Skip LLM summarization entirely. Articles still surface (poller stamps summary_model='disabled').
EMBER_DISABLE_IMAGES0Drop article hero images at ingest.
EMBER_ALLOW_PRIVATE_URLS0Bypass the SSRF block so feeds on RFC1918 / loopback addresses can be subscribed. Only set this if you trust every user who can add feeds.
EMBER_PUBLIC_URLCanonical scheme://host users hit, e.g. https://reader.example.com. Required to enable passkey / WebAuthn sign-in.
EMBER_SECURE_COOKIES1Secure flag on the session + CSRF cookies. Ember serves plain HTTP and expects a TLS-terminating proxy in front, so leave this on. Set 0 only for a deliberate plain-HTTP deployment (e.g. private VPN) — otherwise browsers drop the cookies over HTTP and login silently fails.
EMBER_TRUSTED_PROXIESComma/space-separated CIDRs or IPs of the proxy in front of Ember. X-Real-IP (rate-limit keying) and X-Forwarded-Proto (HTTPS detection for HSTS) are honored only from these peers. Empty = trust nobody (Ember is the edge; reads the real client from the connection). The bundled compose sets this to the Caddy bridge range.
EMBER_SMTP_HOSTSMTP server hostname. Required to enable the daily-digest email feature. Can also be set per-server in Settings → Email / SMTP (admin), which takes precedence.
EMBER_SMTP_PORT587SMTP port. Overrideable in Settings → Email / SMTP.
EMBER_SMTP_USERSMTP auth username (optional; omit for relays without auth). Overrideable in Settings → Email / SMTP.
EMBER_SMTP_PASSWORDSMTP auth password. Overrideable in Settings → Email / SMTP (stored write-only — never echoed back to the UI).
EMBER_SMTP_FROMFrom: address used on digest emails. Overrideable in Settings → Email / SMTP.
EMBER_SMTP_STARTTLS1STARTTLS on submission ports (587). When on, the server must offer STARTTLS or the send fails (no silent plaintext downgrade). Set 0 only for a loopback relay (localhost / 127.0.0.1 / ::1) — plain SMTP to any remote host is refused so credentials never cross the network in the clear. Overrideable in Settings → Email / SMTP.
EMBER_FRESH_WINDOW6hHow recent an article must be to appear in the "Fresh" smart view.
EMBER_POLL_CONCURRENCY8Number of feed-fetch worker goroutines.
EMBER_POLL_TICK60sHow often the poller scans for feeds due to fetch.
EMBER_SESSION_TTL24hLifetime of a freshly-issued session cookie. Go duration (e.g. 30m, 12h, 168h). Range-validated (5m–90d). Admin UI override in Settings → Sessions takes precedence when set.
EMBER_LOG_LEVELinfodebug / info / warn / error.
EMBER_TEST_MODE0Seeds fake admin + articles; loosens cookie Secure flag; and (when EMBER_SESSION_KEY is unset) falls back to a hardcoded, publicly-known session signing key — session cookies become forgeable. Logs a loud warning at startup. Never enable in production.

Runtime settings (persist across restarts)

Stored in the app_settings KV. Edit via the admin UI in Settings → ....

SettingWhere to change
Active LLM modelLanguage model
Temperature / Top P / Context windowLanguage model → Tuning
Session cookie TTL (overrides EMBER_SESSION_TTL)Sessions
App name, page title, favicon URLBranding
Backup schedule + retention (db_backup_keep, default 7)Database
Cleanup schedule + window (db_cleanup_older_days, default 90)Database
OPML export schedule + retention (opml_keep, default 12)Database
SMTP host / port / username / password / from / STARTTLSEmail / SMTP
Initial feed-backlog window (default 48 hours; 0 = no gate)Email / SMTP → Initial backlog window

Each user also has client-side preferences stored in browser localStorage:

PreferenceDefaultKey
ThemeAuto (OS)ember:theme
Article densityCardsember:density
Sidebar collapsedOpenember:sidebar
AI summary card visibleOnember:show-summary
Summary card collapsedOpenember:summary-collapsed
Custom theme paletten/aember:custom

Hardware-aware model recommendation

Run ember probe (or open the admin Language model page) to see a recommendation based on detected RAM, CPU count, and GPU.

RAMGPURecommended
< 2 GiBDisable summaries
2–4 GiBqwen2.5:0.5b
4–8 GiBqwen2.5:0.5b
8–16 GiBqwen2.5:1.5b
16 GiB+qwen2.5:3b
anyNVIDIA / Apple Siliconqwen2.5:7b

Stack-level env vars (docker-compose)

These configure the bundled deploy/docker-compose.yml stack rather than the Ember binary itself.

VarDefaultNotes
EMBER_HOSTNAMElocalhostHostname Caddy serves. Real DNS name → automatic Let's Encrypt.
CADDY_EMAILadmin@localhostEmail registered with Let's Encrypt for ACME notifications. Set this when using a real hostname.
EMBER_HTTP_PORT80Host port Caddy publishes for HTTP. Change when 80 is taken locally.
EMBER_HTTPS_PORT443Host port Caddy publishes for HTTPS. Change when 443 is taken locally.
EMBER_DISABLE_HTTPS_REDIRECT(unset)Set to 1 to turn off Caddy's default 80 → 443 redirect. Use when an upstream proxy already terminates TLS.

If you change the ports, reach the site at the mapped port — e.g. EMBER_HTTPS_PORT=8443 → visit https://localhost:8443. Inside the container Caddy still listens on 80/443; only the host-side mapping changes.

Let's Encrypt

Caddy fetches a free Let's Encrypt cert automatically when all three of these are true:

  1. EMBER_HOSTNAME is a real DNS name that resolves to this server (e.g. ember.example.com).
  2. CADDY_EMAIL is a valid email address.
  3. The public internet can reach port 80 (HTTP-01 challenge) or port 443 (TLS-ALPN-01 challenge) on this host.

If you remap EMBER_HTTP_PORT / EMBER_HTTPS_PORT and expect Let's Encrypt to issue certs, ensure your public ingress (router / upstream proxy / Cloudflare) still terminates on 80/443 and forwards to your mapped host ports. For homelab use with tls internal in the Caddyfile, any ports work fine.

HTTP → HTTPS redirect

Caddy redirects port 80 to 443 by default for any site with managed TLS. Set EMBER_DISABLE_HTTPS_REDIRECT=1 in .env to turn this off — needed when Ember sits behind another reverse proxy (Traefik, nginx, Cloudflare Tunnel, etc.) that already handles the redirect or terminates TLS upstream.

Reverse proxy

Ember expects TLS to be terminated upstream. The reference Caddyfile in deploy/Caddyfile covers:

  • Automatic Let's Encrypt for a real hostname (default).
  • tls internal for self-signed homelab certs.
  • EMBER_DISABLE_HTTPS_REDIRECT toggle for the 80 → 443 redirect.
  • Forwarding X-Real-IP + X-Forwarded-Proto (Ember honors these only from peers listed in EMBER_TRUSTED_PROXIES; the bundled compose sets it to the Caddy bridge range). Without it, Ember treats itself as the edge and ignores both headers.

If you front Ember with Cloudflare, set the authenticated origin pull so only Cloudflare can reach your origin.

Released under the MIT License.