Deploy & admin
Environment variables
Every variable that changes production behaviour, what it controls, and - more usefully - what happens when it is left unset, since most of them fail quietly rather than loudly.
Deploy & admin guide for day and boarding schools.
Last updated August 29, 2026
Configuration comes from tracked templates in the repository root and a server-specific .env.prod that the deploy merges into .env. Secrets never belong in the repository. The table below is arranged around a question the variable names do not answer on their own: what actually happens if you leave it out. Most of these degrade silently, which is why a school can run for a fortnight before noticing that no reminder has ever been sent.
Required - the application is not usable without these
| Variable | Controls | If unset |
|---|---|---|
| DATABASE_URL | MySQL connection for the app and the deploy checks | Deploy stops at the connectivity check; nothing starts |
| NEXTAUTH_SECRET | Signs session tokens, and is the fallback for the activity ingest and /manage session secrets | Sessions cannot be issued, so nobody can sign in |
| NEXTAUTH_URL | Canonical URL for auth callbacks and redirects | Sign-in redirects to the wrong host and sessions appear to drop |
| NEXT_PUBLIC_SITE_URL and APP_URL | Links inside emails, PDFs, receipts, and notification deep links | Emails go out with localhost links that families cannot open |
| MANAGE_USERNAME and MANAGE_PASSWORD | The /manage operations console, which is separate from school sign-in | The operations console is unavailable until unique credentials are configured |
Optional - features that are simply absent until set
| Variable | Controls | If unset |
|---|---|---|
| SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, FROM_EMAIL | Every outbound email: verification, resets, magic links, receipts, admissions | Nothing is emailed; magic-link sign-in becomes unusable for parents |
| FEES_ONLINE_PAYMENT_MODE and its NEXT_PUBLIC_ mirror | Checkout mode: simulated, razorpay, stripe, telr, or disabled | Resolves to disabled and the pay-online screen is switched off |
| RAZORPAY_*, STRIPE_*, TELR_* | Credentials for whichever live gateway you selected | Live checkout fails; only simulated mode still works |
| FEES_CRON_SECRET | Header auth for scripts/run-school-cron.sh | Every daily job returns 401, so autopay, dunning, reminders, and retention purges never run |
| ADMISSIONS_CRON_SECRET | Automatic expiry of admission offers | Offers stay open until staff close them by hand |
| ACTIVITY_LOG_HOT_DAYS | How long activity rows stay queryable | Defaults to 90 days, and only purges when the daily cron runs |
| TRANSPORT_GPS_RETENTION_DAYS, TRANSPORT_BOARDING_RETENTION_DAYS | Retention for vehicle location and boarding scan history | Defaults to 30 days and 730 days respectively |
| ERROR_WEBHOOK_URL | Posting errors and alerts to your own endpoint | Errors go only to the server journal |
| HEALTH_DIAGNOSTICS_SECRET | The detailed variant of GET /api/health | Only the basic database ping is available to your monitoring |
| AI_WORKER_ENABLED and AI_MODEL_PATH | The local AI assistant sidecar | AI Tools report not ready; no external model is called |
| Pre-migrate MySQL dump | Full export before npm run deploy and npm run update | Required. A missing mysqldump stops the update, and older dumps are kept |
| SCHOOLYI_TENANT_MODE | Tenancy mode | Defaults to single_school; strict_multi_school deliberately fails closed |
Common questions
Quick answers in plain language.
Which variables must be changed before a school goes live?+
Set unique values for NEXTAUTH_SECRET, MANAGE_USERNAME, MANAGE_PASSWORD, and FEES_CRON_SECRET before go-live. Store them only in the server environment, rotate them under the operations runbook, and never publish or reuse template credentials.
Why does online fee payment stay switched off even though the keys are present?+
Because the mode, not the keys, decides. With FEES_ONLINE_PAYMENT_MODE unset the resolver falls back to disabled, and the parent-facing UI reads NEXT_PUBLIC_FEES_ONLINE_PAYMENT_MODE separately, so both have to agree. Check the resolved value at /fees/settings/payment-gateway, which shows which keys are present without revealing them.
Where do these values actually live on the server?+
deploy/update.sh merges .env.prod into .env on each deploy, and only reads those two files from the repository root - never a file under deploy/. Editing the merged .env directly works until the next deploy overwrites it, so put durable values in .env.prod.
Related searches
School leaders and IT teams often search for: how to environment variables in school management software, best school ERP implementation for K-12 schools, Schoolyi environment variables guide, school software deployment, MySQL school database backup, and school SaaS hosting.

