Configuration
Every environment variable YourDesk reads, with defaults and when it is read, plus the Ops and workspace settings that live in the database instead.
6 min readUpdated Oct 17, 2026Applies to YourDesk 1.0.0
On this page
YourDesk is configured in three places:
- Environment variables bootstrap the app: the database, the session secret, the public origin, Google sign-in and the platform xAI key.
- The Ops console (platform admins) holds deployment-wide settings in the database: sign-up, plans and payment provider keys. See First admin and the Ops console.
- Settings inside each studio hold that studio's own details: logo, currency, bank details, mailbox, team and a personal xAI key. See Your desk.
Stripe and PayPal keys are not environment variables. They are entered in Ops → Payments and stored encrypted in the database.
An empty or whitespace-only value counts as unset for the variables the server reads at runtime.
Required in production
| Variable | Default when unset | What it does |
|---|---|---|
DATABASE_URL |
Embedded PGLite in ./data/pglite (/tmp/yourdesk on Vercel) |
Postgres connection string, for example postgresql://user:pass@host/db?sslmode=require. |
BETTER_AUTH_SECRET |
With NODE_ENV=production, none: the server refuses to start. Otherwise a random value per process |
Signs sessions. Its SHA-256 hash is also the AES-256-GCM key for stored mailbox passwords, payment keys and personal xAI keys. Generate with openssl rand -hex 32 and never change it. |
BETTER_AUTH_URL |
Vercel's production or deployment URL on Vercel; otherwise localhost, 127.0.0.1 and [::1] on PORT |
Your public origin with no trailing slash, for example https://desk.example.com. Sign-in rejects other origins with "Invalid origin". Stripe and PayPal checkout build their return addresses from it, falling back to http://127.0.0.1:8080. |
Important
A server running with NODE_ENV=production refuses to start without BETTER_AUTH_SECRET and logs how to generate one. The Docker image and Vercel set NODE_ENV=production for you; a plain Node install only gets this check if you set NODE_ENV=production yourself. Without that check, a missing secret means sessions end on every restart and secrets are sealed with a machine-local key file (data/mail.key) instead. Always set it, and check Ops → System, which shows whether it is set.
Optional
| Variable | Read | Default | What it does |
|---|---|---|---|
VITE_PUBLIC_HOSTNAME |
Build time | Unset | Hostname only (desk.example.com). Adds the https://<host>/og.jpg share image to link previews. Compiled into the build: rebuild after changing it. See Docker builds. |
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET |
Runtime (start) | Unset | Both set turns on "Continue with Google". See Integrations. |
XAI_API_KEY |
Runtime | Unset | Platform-wide xAI key, used when a user and their studio owner have no personal key. |
XAI_AGENT_MODEL |
Runtime (start) | grok-4.6 |
Model for the Agent. The other AI helpers (lead research, letter writing) always use grok-4.5. |
PORT |
Runtime | 3000 for the built Node server; the Docker image sets 8080; npm run dev always uses 8080 |
Listening port. NITRO_PORT is also accepted. Also used for the local origins sign-in trusts when BETTER_AUTH_URL is unset. |
HOST |
Runtime | All interfaces (the Docker image sets 0.0.0.0) |
Listening address. NITRO_HOST is also accepted. |
YOURDESK_DEMO |
Runtime | Off, except for a local trial: npm run dev with no DATABASE_URL, opened on localhost or 127.0.0.1 |
Exactly 1 turns on the shared, read-only demo account and its Log in to demo account button. Leave it unset on a real install. See Demo mode. |
NODE_ENV |
Runtime | production in the Docker image and on Vercel; unset for node .output/server/index.mjs unless you set it |
production makes the server refuse to start without BETTER_AUTH_SECRET instead of using the development fallbacks. |
NITRO_PRESET |
Build time | vercel |
node_server builds a plain Node server. npm run build:node and the Dockerfile set it for you. |
Local and development only
| Variable | Default | What it does |
|---|---|---|
YOURDESK_SEED |
Off | Exactly 1 fills every newly created account with sample data, on any database. Never set it in production. |
YOURDESK_DATA_DIR |
./data (/tmp/yourdesk on Vercel) |
Where the embedded database and the fallback key file live. |
VITE_AUTH_ENABLED |
Sign-in on | Exactly false turns sign-in off and shares one "Dev User". Refused when DATABASE_URL is set: every request then fails rather than sharing one user on a real database. |
VERCEL, VERCEL_URL, VERCEL_BRANCH_URL and VERCEL_PROJECT_PRODUCTION_URL are set by Vercel itself and used for its preview URLs; you never set them.
Where .env is read
| Command | Reads .env files? |
|---|---|
npm run dev |
Yes: .env, .env.local and the mode-specific variants |
vite build (inside npm run build and npm run build:node) |
Yes, which is how VITE_ variables are compiled in |
node scripts/migrate.mjs |
No. Use node --env-file=.env scripts/migrate.mjs |
npm start, node .output/server/index.mjs |
No. Use --env-file, your process manager's environment file, or the platform's variables |
| Docker | Only through --env-file or env_file: at run time; .env is excluded from the image |
Settings in the Ops console
These are stored in the database and edited by platform admins. They are not environment variables.
| Screen | Setting | What it does in 1.0.0 |
|---|---|---|
| Product | Sign-up open or closed | Enforced for every sign-up path (email and Google). People holding a pending team invite can still create an account with the invited address. |
| Product | Feature flag signup | Off has the same effect as "Signup closed". |
| Product | Feature flag agent | Off hides the Agent from the sidebar and top bar, and the server refuses Agent conversations, runs, memories and automations. Letter drafting in Client updates and lead research in Discover are not covered by this flag. |
| Product | Feature flag mail | Off hides Settings → Workspace → Mailbox, the server refuses connecting, syncing and sending through a mailbox, and automatic client emails stop. Send reminder falls back to a Gmail compose window. |
| Product | Feature flag portals | Off hides Client portals from the sidebar, and every client portal link shows as closed and refuses its actions. Studios can still manage portals. Proposal and invoice links are not affected. |
| Product | Feature flag discover | Off hides Discover from the sidebar, and the server refuses lead research, saving answers and converting a lead. |
| Product | Tagline | Shown under the heading of the public /pricing page. |
| Product | Maintenance message | Shown as a notice on the /pricing page only. |
| Product | Brand name | Used as the brand name on the PayPal checkout page only. |
| Product | Mark, support email, default currency | Saved, but not displayed or used anywhere. |
| Plans | Plans | The plans on the public /pricing page. See Selling it as SaaS. |
| Payments | Stripe and PayPal | Keys, mode and on/off. Secrets are encrypted with the key derived from BETTER_AUTH_SECRET. |
Note
The product name shown across the app, the marketing pages and page titles is APP_NAME in src/lib/brand.ts, not the Ops brand name. Rebranding the interface is a code change; the FAQ lists the files.
Studio settings
Each studio sets its own details under Settings; they do not affect other studios.
| Where | Setting | Default |
|---|---|---|
| Settings → Workspace → Studio brand | Logo (image up to about 900 KB), legal name, currency, accent colour, bank details, PayPal handle | Currency AUD |
| Settings → Workspace → FX rates | Manual exchange rates, or refresh from the free Frankfurter API | None |
| Settings → Workspace → Mailbox | IMAP and SMTP mailbox for sending and syncing | None |
| Settings → Workspace → Mailbox | Email clients automatically: send overdue-invoice reminders and proposal follow-ups without asking. Only the studio owner can change it. See Automatic reminders. | Off |
| Settings → Workspace → Studio seats | Team invitations | Just the owner |
| Settings → Agent | Personal xAI key | Falls back to the studio owner's key, then XAI_API_KEY |
| Settings → Profile | Display name, which is also the studio name clients see on links | Your sign-up name |
A complete production example
# Required
DATABASE_URL=postgresql://yourdesk:change-me@db:5432/yourdesk
BETTER_AUTH_SECRET=64-hex-characters-from-openssl-rand
BETTER_AUTH_URL=https://desk.example.com
# Recommended (compiled in at build time)
VITE_PUBLIC_HOSTNAME=desk.example.com
# Node server (the Docker image sets these itself)
NODE_ENV=production
PORT=8080
HOST=127.0.0.1
# Optional
GOOGLE_CLIENT_ID=1234.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=...
XAI_API_KEY=xai-...
XAI_AGENT_MODEL=grok-4.6