Skip to content

Environment Variables

Amanbig edited this page Jul 20, 2026 · 2 revisions

Environment Variables

The README's Configuration Parameters table covers the essentials. This is the full list, including a few that don't show up there yet.

Core

Variable Description Default Required
PORT Port the backend server listens on. 7780 No
DB_TYPE PGLITE for the embedded database, or anything else to use DATABASE_URL against an external Postgres. PGLITE Yes
DB_DIR Directory to persist PGlite's data files. ./manup Only for DB_TYPE=PGLITE
DATABASE_URL Connection string for an external Postgres instance. postgres://postgres:password@localhost:5432/manup Only if DB_TYPE is not PGLITE
MASTER_KEY 32-character hex key used to encrypt/decrypt secret values at rest. Losing this makes all stored secrets unrecoverable — back it up outside the container. Yes
JWT_SECRET Signs short-lived access-token cookies. Yes
REFRESH_TOKEN_SECRET Signs long-lived (7-day) refresh tokens. Must be a different value from JWT_SECRET — it's a separate secret specifically so access and refresh tokens can't be swapped for each other. Yes
ALLOWED_ORIGINS Comma-separated list of origins allowed by CORS. If unset, defaults to same-origin (http://localhost:<PORT>) plus http://localhost:5173 for local Vite dev. No

Email (optional — org member invites)

Only used to email temporary credentials when inviting a new member to an organization. If any of these are missing, invite emails are silently skipped (the invite still succeeds — you'll just need to relay the credentials another way).

Variable Description Default
SMTP_HOST SMTP server host. — (unset = email sending disabled)
SMTP_PORT SMTP server port. 465 is treated as implicit TLS. 587
SMTP_USER SMTP auth username.
SMTP_PASS SMTP auth password.
SMTP_FROM From: address on outgoing invite emails. ManUp Secure Vault <no-reply@manup.io>

Production checklist

  • Never run with the default JWT_SECRET/MASTER_KEY values (development) — the server refuses to start with those in NODE_ENV=production on purpose. REFRESH_TOKEN_SECRET is not currently covered by that startup guard, so double-check it yourself before going to production — don't leave it at development-refresh.
  • Generate JWT_SECRET and REFRESH_TOKEN_SECRET as two independent random values — don't reuse one for both.
  • MASTER_KEY must be a 32-character hex string. Store it somewhere durable outside the container/volume (a secrets manager, a password manager, etc.) — it's not recoverable from the database.

Clone this wiki locally