Skip to content

Reference › Configuration

Configuration

spellcache reads one .env at the repository root: the Next.js app, the worker, drizzle-kit, Playwright, and docker compose for ${...} interpolation in docker-compose.example.yml. Never commit it.

Terminal window
cp .env.example .env

The tables below are read from .env.example each time the site is built. required variables must be set; optional ones have a default and are commented out in the file. Uncomment a line only to change its default: an empty value is not the same as an unset one.

Development

Running the app on your machine with pnpm dev. Self-hosting reads these too.

VariableStatusDescription
DATABASE_URLrequiredPostgreSQL connection string, as seen from where the code runs. Matches the postgres service of docker-compose.yml. In production (section 4), this is the host's view, used by the backup scripts only — containers get their own URL from the Compose file.
REDIS_URLoptionalRedis/Valkey connection string. Search cache, worker job queue and rate limits. Without it, search is uncached and rate limits fall back to an in-memory counter. Default: unset.
THUMBNAILS_DIRoptionalDisk cache of card thumbnails served by the image proxy. Default: thumbs/ in the web app's working directory. Containers use /app/thumbs (a volume).
AUTH_SECRETrequiredSecret that signs session cookies (Auth.js). Generate it once and keep it: changing it signs everyone out.
openssl rand -base64 32
RESEND_API_KEYoptional in development, required in productionResend API key, used to send sign-in emails. Without it, in development only, sign-in links are printed in the pnpm dev console.
RESEND_FROM_EMAILoptional in development, required in productionSender of sign-in emails, "Name <address>". Its domain must be verified in Resend. Default: spellcache <onboarding@resend.dev>, Resend's test sender, which only delivers to your own Resend account address.
ADMIN_EMAILoptional in development, required in productionEmail of the first administrator: only this address may create the first account of an empty database, and it becomes admin. Unset: in development (no RESEND_API_KEY) the first account created becomes admin; with RESEND_API_KEY set, no first account can be created at all.

Production

Self-hosting with docker-compose.example.yml.

VariableStatusDescription
SPELLCACHE_VERSIONoptionalImage version to run: 1.2.3, 1.2, or latest. Default: latest.
POSTGRES_USER
POSTGRES_PASSWORD
POSTGRES_DB
requiredPostgreSQL credentials and database name for the postgres service. The password ends up in a URL: keep it alphanumeric to avoid encoding it.
REDIS_PASSWORDrequiredPassword of the redis (Valkey) service. Like the Postgres one, it ends up in a URL: keep it alphanumeric.
openssl rand -hex 24
AUTH_URLrequiredFull public URL of the app, scheme included (e.g. https://spellcache.example). Used to build sign-in links.
WEB_BIND
WEB_PORT
optionalInterface and port on which the web container is published on the host, for your own reverse proxy. Defaults: 127.0.0.1 and 3000.

Worker

The nightly import schedule, for development and production.

VariableStatusDescription
WORKER_NIGHTLY_AT
WORKER_TIMEZONE
optionalLocal time ("HH:MM") of the nightly import and revaluation, and the IANA time zone it is read in. Defaults: 03:15 and UTC. A worker restarted within the hour after that time still runs the night; later, it waits for the next one.
WORKER_NIGHTLY_HOUR_UTCoptional, legacyUTC hour (0-23) of the nightly run. Ignored when WORKER_NIGHTLY_AT is set.
WORKER_HEALTH_PORToptionalPort of the worker's internal health check (GET /health), never published outside the Docker network. Default: 8081.

Backup

deploy/backup.sh and deploy/restore.sh, run on the host.

Not read by docker compose: the scripts read them from the cron job's or the shell's environment (see docs/self-hosting/scheduled-tasks.md). DATABASE_URL (section 1) must then point to 127.0.0.1:5432, where docker-compose.example.yml publishes Postgres:

postgres://<POSTGRES_USER>:<POSTGRES_PASSWORD>@127.0.0.1:5432/<POSTGRES_DB>
VariableStatusDescription
BACKUP_DESTrequired for backupsOff-server destination of the encrypted archive:
file:///absolute/path       — local or mounted remote disk
ssh://user@host:/path       — copy with scp, rotation over ssh
BACKUP_PASSPHRASErequired for backupsPassphrase of the archive's AES-256 encryption. Keep a copy somewhere else than the server: no archive can be restored without it.
openssl rand -base64 32
BACKUP_RETENTION_DAYSoptionalDays of archives kept at the destination. Default: 30.