-e flags or an environment: block in your Compose file. When running from source, place them in a .env file at the project root.
Only two variables are required to start Atrium. Everything else has a sensible default.
App URLs
By default Atrium auto-detects its URLs. You only need to set these explicitly when your API and web app are deployed on separate hostnames, or when Atrium is running behind a reverse proxy on a non-standard port.string
default:"http://localhost:3000"
Public URL of the web frontend. The API uses this for CORS and Content Security Policy. Set this to the domain where your users access Atrium (e.g.,
https://portal.yourcompany.com).string
default:"http://localhost:3001"
Internal URL the web server uses to call the API server-to-server. In a single-container deployment this stays at the default. In a split deployment, point this at your API service.
string
default:"http://localhost:3001"
Browser-facing API URL. Must be reachable from your users’ browsers, so set this to a public hostname in production split-deployment setups.
Database
string
required
PostgreSQL connection string. Format:
postgresql://user:password@host:5432/dbname?schema=publicWhen using the built-in database (USE_BUILT_IN_DB=true, the default), this is generated automatically and you can leave it unset. When connecting to an external database you must provide it.string
A non-pooled (direct) connection string used exclusively for schema migrations. Required when your
DATABASE_URL points to a connection pooler such as PgBouncer or Supabase’s Transaction Mode pooler, which don’t support the CREATE INDEX CONCURRENTLY statements that migrations use.boolean
default:"true"
Controls whether the Docker image starts its bundled PostgreSQL instance. Set to
false and provide DATABASE_URL when you want to use your own database server.boolean
default:"false"
When
true, Atrium skips the automatic schema sync that runs on startup. Use this when your database connection goes through a pooler that doesn’t support schema migrations (e.g., PgBouncer). Provide a DIRECT_URL for a non-pooled connection so schema sync can run separately.Auth
string
required
Secret key used to sign and verify authentication tokens. Must be at least 32 characters long and unique per deployment. The API will not start in production if this is set to the default placeholder value.Generate a suitable value with:
Storage
See File Storage for a full guide on each backend.string
default:"local"
The file storage backend to use. Accepted values:
local, s3, minio, r2.string
default:"./uploads"
Directory where files are stored when
STORAGE_PROVIDER=local. Must be a mounted Docker volume to survive container restarts.string
default:"atrium"
Name of the S3 (or S3-compatible) bucket. Used by the
s3, minio, and r2 providers.string
default:"us-east-1"
AWS region of the bucket. For MinIO and R2 this is still required by the SDK but the value is not significant —
us-east-1 works.string
Custom S3-compatible endpoint URL. Required for
minio and r2. Not used for the standard s3 provider. Example: https://your-account.r2.cloudflarestorage.com.string
Access key ID for the storage provider. Required for
s3, minio, and r2.string
Secret access key for the storage provider. Required for
s3, minio, and r2.number
default:"50"
Maximum file size allowed for uploads, in megabytes. Applies to all storage backends.
string
API key from your Resend account. Required to send magic link login emails, client invitations, and password reset emails. If unset, Atrium displays a setup wizard on first launch.
string
default:"noreply@yourdomain.com"
The sender address shown on all outbound emails. Must be from a domain you have verified in your Resend account.
Payments
These variables enable client invoice payments via Stripe. All are optional — leave them unset if you don’t need Stripe payments. For Stripe Connect mode you also needSTRIPE_MODE and the corresponding secret key. See Stripe Connect for the full setup guide.
string
Stripe Connect platform client ID (starts with
ca_). Required for Stripe Connect mode. Enables the “Connect with Stripe” OAuth flow so clients can pay invoices directly.string
Webhook signing secret for Stripe Connect events (starts with
whsec_). Required for Stripe Connect mode.string
default:"test"
Controls which Stripe environment to use. Accepted values:
test, live. Used with Stripe Connect mode.string
Your platform Stripe secret key for test mode (starts with
sk_test_). Used with Stripe Connect mode when STRIPE_MODE=test.string
Your platform Stripe secret key for live mode (starts with
sk_live_). Used with Stripe Connect mode when STRIPE_MODE=live.string
default:"usd"
ISO 4217 currency code for invoice payments. Examples:
usd, eur, gbp. Applies to all invoices across the organization.Security
boolean
default:"true"
Controls the
Secure flag on session cookies. Defaults to true when NODE_ENV=production.You should only set this to false if Atrium is accessed over plain HTTP with no TLS-terminating reverse proxy anywhere in the chain — for example, a local Unraid installation without HTTPS.boolean
default:"false"
Enable only when deploying the web app behind Firebase Hosting. Applies a cookie workaround required by the Firebase CDN.
Analytics
string
A JSON array of script tag attribute objects. Each object is serialized into a Each key in the object becomes an attribute on the rendered
<script> tag in the web app’s <head>. You can add any script-based analytics provider — Umami, Plausible, Fathom, and others are supported.<script> element. You can add multiple trackers by adding more objects to the array.Advanced
string
default:"info"
Log verbosity level for the API, using Pino’s log levels. Accepted values (least to most verbose):
fatal, error, warn, info, debug, trace.number
default:"100"
Maximum number of API requests per minute, per IP address. Raising this limit is useful when running end-to-end tests locally to avoid cascading 429 errors.
number
default:"5"
Maximum number of signup requests per minute, per IP address. Separate from the general
THROTTLE_LIMIT to limit abuse of the registration endpoint.