EngineeringEnvironment variables

Environment variables

Complete reference for every environment variable across the NexSchool services (server, admin-web, panel, client) and the deployment infrastructure.

All environment files live in school-erp-infra/env/:

FilePurpose
.env.local.exampleTemplate for local development
.env.localLocal dev secrets (never commit)
.env.prod.exampleTemplate for production
.env.prodProduction secrets (never commit, lives on EC2)

Never commit secrets

  • Never commit .env.local or .env.prod to git. Only commit .env.*.example files with placeholder values.
  • If a secret is accidentally committed, rotate it immediately — removing it from the next commit is not enough, because git history retains it.
  • The tables below use placeholders such as <set-in-secrets-manager> wherever the source held a real-looking secret. Never paste actual credentials into docs, examples, or committed files.
  • JWT_SECRET and SECRET_KEY must be cryptographically random strings of at least 32 characters in production.
  • Production DATABASE_URL must only be reachable from the EC2 security group (RDS private subnet).

Backend (server/)

VariablePurposeRequired?Default/example
DATABASE_URLSQLAlchemy connection stringYespostgresql://user:pass@postgres:5432/school_erp
REDIS_URLGeneral cache backendYesredis://redis:6379/0
CELERY_BROKER_URLCelery task queue brokerYesredis://redis:6379/0
CELERY_RESULT_BACKENDCelery result storageYesredis://redis:6379/0
JWT_SECRETSigns JWT access tokensYes<set-in-secrets-manager>
JWT_REFRESH_SECRETSigns refresh tokens (may reuse JWT_SECRET)No<set-in-secrets-manager>
SECRET_KEYFlask session secretYes<set-in-secrets-manager>
FLASK_ENVControls debug modeYesdevelopment / production
FLASK_APPFlask app entry (for CLI)Noapp:create_app
DEFAULT_TENANT_SUBDOMAINFallback tenant for local devNodemo
ALLOWED_ORIGINSCORS allowed originsNohttp://localhost,http://panel.localhost
AWS_ACCESS_KEY_IDS3 file uploadsNo<set-in-secrets-manager>
AWS_SECRET_ACCESS_KEYS3 file uploadsNo<set-in-secrets-manager>
AWS_S3_BUCKETS3 bucket nameNonexschool-uploads
AWS_REGIONS3 regionNoap-south-1
CLOUDINARY_URLStudent document storageNocloudinary://<set-in-secrets-manager>
CLOUDINARY_CLOUD_NAMECloudinary cloudNonexschool
CLOUDINARY_API_KEYCloudinary API keyNo<set-in-secrets-manager>
CLOUDINARY_API_SECRETCloudinary API secretNo<set-in-secrets-manager>
MAIL_SERVERSMTP server for emailsNosmtp.gmail.com
MAIL_PORTSMTP portNo587
MAIL_USERNAMESMTP userNonoreply@nexschool.com
MAIL_PASSWORDSMTP passwordNo<set-in-secrets-manager>
MAIL_USE_TLSTLS for emailNotrue
FIREBASE_CREDENTIALS_JSONFirebase Admin SDK JSON (push notifications)No<set-in-secrets-manager>
MAX_CONTENT_LENGTHMax upload size in bytes (64 MB default); keep in sync with nginx client_max_body_sizeNo67108864
GUNICORN_THREADSgthread pool size per worker; must exceed peak concurrent SSE streamsNo16
LOG_LEVELLogging levelNoINFO

Admin Web (admin-web/)

Only NEXT_PUBLIC_* vars are accessible in browser code. Others are server-side only.

VariablePurposeRequired?Default/example
ADMIN_WEB_BASE_URLBase URL used to build password-reset and login links. Set this in production — see the callout below.Yes (prod)https://<tenant>.nexschool.com
NEXT_PUBLIC_API_URLBase URL for all API callsYeshttp://localhost/api
NEXT_PUBLIC_GATEWAY_ORIGINBrowser-facing originYeshttp://localhost
NEXT_PUBLIC_PANEL_URLLink to super-admin panelNohttp://panel.localhost
NEXT_PUBLIC_FIREBASE_API_KEYFirebase web app configNo<set-in-secrets-manager>
NEXT_PUBLIC_FIREBASE_AUTH_DOMAINFirebase auth domainNoproject.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_IDFirebase projectNonexschool-prod
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKETFirebase storageNonexschool-prod.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_IDFirebase messagingNo123456789
NEXT_PUBLIC_FIREBASE_APP_IDFirebase app IDNo1:123:web:abc
NEXT_PUBLIC_FIREBASE_VAPID_KEYWeb push VAPID keyNo<set-in-secrets-manager>

Set ADMIN_WEB_BASE_URL in production. Password-reset and login links are generated from this base URL. If it is unset, links fall back to localhost and will not work for real users. Point it at the tenant-facing admin-web origin before enabling password reset or login-link flows.

Super-admin Panel (panel/)

VariablePurposeRequired?Default/example
NEXT_PUBLIC_API_URLSame API as admin-webYeshttp://localhost/api
NEXT_PUBLIC_GATEWAY_ORIGINPanel’s own originYeshttp://panel.localhost

Mobile App (client/)

Expo uses .env or app.config.js. Variables must be prefixed EXPO_PUBLIC_ to be accessible in app code.

VariablePurposeRequired?Default/example
EXPO_PUBLIC_API_URLLAN IP for physical deviceYeshttp://192.168.1.x/api
EXPO_PUBLIC_TENANT_SUBDOMAINDefault tenant for devNodemo

Docker Compose (infra)

Set in school-erp-infra/env/.env.local or .env.prod. Compose substitutes these into service configs.

VariablePurposeRequired?Default/example
ECR_API_URLFull ECR image URL for API (prod compose)Yes (prod)<account>.dkr.ecr.ap-south-1.amazonaws.com/nexschool-api
ECR_ADMIN_WEB_URLFull ECR image URL for admin-web (prod compose)Yes (prod)<account>.dkr.ecr.ap-south-1.amazonaws.com/nexschool-admin-web
ECR_PANEL_URLFull ECR image URL for panel (prod compose)Yes (prod)<account>.dkr.ecr.ap-south-1.amazonaws.com/nexschool-panel
POSTGRES_USERDB user (postgres service)Yes<set-in-secrets-manager>
POSTGRES_PASSWORDDB password (postgres service)Yes<set-in-secrets-manager>
POSTGRES_DBDB name (postgres service)Yesschool_erp

GitHub Actions secrets

Configured in the repository/organization secrets store, not in .env files. Consumed by the deploy workflows.

SecretPurposeRequired?Default/example
AWS_ROLE_TO_ASSUMEOIDC role for all deploy workflowsYes<set-in-secrets-manager>
EC2_HOSTSSH hostname/IP for deploy SSH stepYes<set-in-secrets-manager>
EC2_SSH_PRIVATE_KEYPEM key for EC2 SSHYes<set-in-secrets-manager>
ECR_REPO_SERVERECR repository URI for API imageYes<set-in-secrets-manager>
ECR_REPO_ADMIN_WEBECR repository URI for admin-web imageYes<set-in-secrets-manager>
ECR_REPO_PANELECR repository URI for panel imageYes<set-in-secrets-manager>
NEXT_PUBLIC_API_URLBuild-time var for Next.js imagesYes<set-in-secrets-manager>
NEXT_PUBLIC_FIREBASE_*Build-time Firebase config for admin-webNo<set-in-secrets-manager>