Skip to main content
Reactive Resume is configured entirely through environment variables. This page lists every variable the server reads, grouped by what it controls. Only three are required: APP_URL, DATABASE_URL and AUTH_SECRET. For a working setup, start with Self-hosting with Docker and come back here when you want to turn on an optional feature.

How values are read

  • The server reads variables from its process environment. In a source checkout it also loads a .env file from the workspace root. A variable already set in the environment always wins over the file.
  • An empty value counts as unset. SMTP_HOST="" is the same as not setting SMTP_HOST at all.
  • Values are validated at startup. If one is missing or malformed, the server stops and names the variable in its logs.
  • Boolean variables accept true or false. 1/0, yes/no and on/off also work; any other value stops the server.
  • Changes take effect after a restart. With Docker Compose, run docker compose up -d to recreate the container with the new environment.
PDFs are rendered by the app itself, so there is no printer service to configure. The v4 and early v5 variables PRINTER_*, BROWSERLESS_* and CHROME_* are no longer read; you can remove them.

Required

Keep AUTH_SECRET the same for the life of your instance. Changing it signs everyone out and makes data encrypted with it unreadable, including two-factor authentication secrets and the keys that sign API and MCP access tokens.

Server

Database

Sign-in

Social sign-in

Each provider appears on the sign-in page once both of its variables are set. See Single sign-on for callback URLs and provider setup.

Custom OAuth or OpenID Connect provider

Use these to sign in through your own identity provider, such as Authentik, Keycloak or Authelia. The provider is turned on when the client ID and secret are set together with either a discovery URL or all three manual endpoints. Its callback URL is APP_URL followed by /api/auth/callback/custom.

Email

Reactive Resume sends email for account verification, password resets and email changes. Sending turns on only when SMTP_HOST, SMTP_USER, SMTP_PASS and SMTP_FROM are all set. Until then, each email is written to the server log instead, so you can still copy verification links from there.

Storage

Uploads such as profile pictures, files attached to applications and Assistant attachments are stored in one of three backends.
Assistant attachments stay private with every backend. Local storage writes them in a separate namespace that public upload routes never serve. General file uploads allow 10 MB; Assistant attachments allow 25 MB per file.
Switching backends does not move files that are already stored. Copy them yourself before you switch.

AI and Redis

For setup instructions and official provider guides, see Job search and AI. To let people bring their own keys, set ENCRYPTION_SECRET. They can then add providers in Settings → AI & developer; see Connecting an AI provider. Alternatively, configure a shared provider with AI_PROVIDER, AI_MODEL and AI_API_KEY (the key is optional for Ollama). Server configuration takes precedence over personal providers for every AI feature, including the Assistant. Settings show that AI is enabled globally and hide personal provider controls; the API also rejects personal provider changes. Existing personal providers remain stored and become available again if you remove the server configuration. Shared credentials stay in the environment and do not require ENCRYPTION_SECRET.
Changing ENCRYPTION_SECRET makes every saved AI and web-access key unreadable. People then need to enter their keys again.
Redis is optional on a single server. Without it, everything works, with these limits:
  • An Assistant reply that is interrupted by a page reload can’t be picked up again.
  • Rate limits, Stop on a running Assistant reply, live updates between open tabs and the check that counts each public resume view once an hour are kept in the memory of one server process.
Set REDIS_URL when you run more than one server process, or when you want replies to survive a reload. When Redis is configured, the health endpoint also checks it. Saved AI providers and Assistant conversations are kept in PostgreSQL, so they remain available without Redis.

Web access

The built-in reader is active without credentials. Search and enhanced reading use one optional connection: Firecrawl, Tavily or Exa. People can select a provider and save one personal key in Settings → AI & developer → Web access when ENCRYPTION_SECRET is configured. Personal connections use official cloud endpoints. For a shared service, set WEB_ACCESS_PROVIDER and WEB_ACCESS_API_KEY. Only Firecrawl accepts a custom WEB_ACCESS_API_URL, including a keyless self-hosted service. Server configuration takes precedence, settings say Provided by the server, and personal changes are rejected. Stored personal connections become available again when the shared configuration is removed. Shared connections do not require ENCRYPTION_SECRET. Explicit generic configuration wins over legacy Firecrawl variables. Incomplete generic configuration, a missing key for Tavily/Exa, or a custom URL for those providers stops startup instead of silently choosing another connection. Connections enable Applications keyword search and assistant web tools. URL import uses the selected reader, then falls back to the built-in reader on recoverable failures. Saving pasted text and manual preparation work without either web-access or AI credentials. Search returns up to five links; choosing a result does not create an application until the user reviews and saves it. Test connection checks search and enhanced reading independently, without reader fallback. Rendering settings does not call external services. Quota and authentication failures leave manual workflows available. See Job search and AI for connection setup, Firecrawl deployment, optional SearXNG search and backup guidance. Public page URLs remain protected against private destinations, redirects and DNS rebinding. A remote reader must enforce these protections internally too. Search queries and selected URLs go to the chosen service; resume data and AI keys do not.

Feature flags

All flags default to false.
Only turn on the two FLAG_ALLOW_UNSAFE_* flags on an instance where you trust every user. On a shared instance, an unsafe AI base URL lets users make your server call internal network addresses, and an unsafe redirect URI can be used for phishing or to steal access tokens.

Deployment aliases

On Vercel (when VERCEL=1), the server fills in some variables from the ones Vercel’s integrations inject. A value you set yourself always wins. Vercel builds also read ALLOW_PREVIEW_MIGRATIONS: preview builds refuse to run migrations unless it is true, so a preview can’t change your production database by accident. See Self-hosting on Vercel.

Development and tooling only

These appear in .env.example but are not used by a running server: See Development setup for working on the code.

Cloudflare Workers

Set CLOUDFLARE=1 in Wrangler. The runtime uses native R2 (STORAGE_BACKEND=r2), disables native image processing, and receives its PostgreSQL connection through the HYPERDRIVE binding. Keep REDIS_URL unset; SQLite Durable Objects provide shared limits, live updates, and cancellation. See Self-hosting on Cloudflare for required bindings, secrets, migrations, and runtime differences.