Loomis
Configuration

The nineteen names

Why half of the configuration is a file and half of it is somewhere else, and how the panel reports both.

The installation has nineteen settings that are read from the environment rather than stored in the database. Database settings are edited in the panel and change instantly. Environment settings are read when a process starts, which is what makes them the right place for keys and addresses, and what makes them the wrong place for anything you change often.

The two homes

That split is not a preference, it is where the code runs. The route that seals a token needs the key that seals it, and that route is in the app. The function that signs a session needs the key that signs it, and that function is on the deployment. A value put in the wrong one is present, looks right, and does nothing.

The failure this prevents

An installation once reported SETTINGS_SECRET as missing while the vault was sealing tokens with it, because the screen was checking the deployment for a name that only the app reads. The panel now says which home it is checking, and it checks both.

Where you set them

Platform → Environment lists all nineteen with their home, what each is for, and whether it is Set, Missing or Not set. It never shows a value, only whether there is one and a four-character hint such as re_...f3a9.

Names the panel is allowed to write, because they are read by the app at request time, can be set from that screen directly. The others show the exact command to run instead, since a deployment's environment is set on the deployment.

Which of them are optional

Two of the nineteen are genuinely optional, and the panel counts them separately so that "unset" does not look like "broken".

NameWhen it is fine to leave unset
ALLOW_SELF_UPDATEAlways, unless you want the panel to update this installation by itself. It must be exactly 1
CREDIT_MONTHLY_CAPAlways. The Credits section has its own ceiling, and the shipped number is used when this is unset

Everything else is either required to start or switches off the feature that needs it. Nothing else breaks the app: Google sign in without Google's two names is a button that says so when it is pressed.

The order that works

The database address first

NEXT_PUBLIC_CONVEX_URL is the one name the app cannot serve without. npx convex dev creates or connects a deployment and prints it. See Convex, set up properly.

The two secrets

SETTINGS_SECRET for the app and BETTER_AUTH_SECRET for the deployment. Two long random strings, and the second one signing everybody out when it changes:

openssl rand -base64 32   # run it twice, once for each

The addresses

NEXT_PUBLIC_APP_URL and SITE_URL, which are the same address in two places. Every callback, every email link and every provider redirect is built from them, so they have to be the address people actually visit. See Addresses and secrets.

The sign-in providers, if you want more than a password

Google and GitHub, each a client ID and a secret. Google sign in and GitHub sign in walk through the consoles screen by screen.

Mail, then the first administrator

RESEND_API_KEY and EMAIL_FROM for the codes, then ADMIN_EMAIL, ADMIN_PASSWORD and ADMIN_NAME. See Email that arrives.

Rotating one

NameWhat happens when it changes
SETTINGS_SECRETEvery sealed token becomes unreadable. Reconnect integrations afterwards
BETTER_AUTH_SECRETEverybody is signed out. Accounts and data are untouched
An OAuth client secretSign in through that provider stops until the new secret is in
NEXT_PUBLIC_CONVEX_URLThe app talks to a different backend. Change it and nothing else
NEXT_PUBLIC_APP_URL or SITE_URLCallbacks and email links change. Update the providers to match

After changing any of them, restart the app. The panel says so on the screens where it matters, and System → Status & health is where you confirm the result.