urmi-ai/docs/ENVIRONMENT.md
2026-10-02 11:22:40 +05:30

8.8 KiB

Urmi environment configuration

This document tracks every environment variable, where it lives, and how it flows through local development and Docker.

Quick start

cp .env.example .env
# Edit .env — at minimum set AUTH_SECRET; add Google vars if using Google sign-in
docker compose up --build

Run services outside Docker

# Terminal 1 — Postgres must already be running (e.g. via compose)
cp backend/.env.example backend/.env

# Terminal 2
cd backend && pip install -r requirements.txt && uvicorn app.main:app --reload

# Terminal 3
cp frontend/.env.example frontend/.env
cd frontend && npm install && npm run dev

Env file locations

File Used by Purpose
.env (repo root) Docker Compose Auth secrets + Google OAuth for the backend container
.env.example (repo root) You Template for Compose
backend/.env FastAPI (local run) Full backend config when not using Compose
backend/.env.example You Template for local backend
frontend/.env Vite (local run) Browser API URL
frontend/.env.example You Template for local frontend

There is no committed .env file. Only .env.example templates are checked in. Copy the relevant example before running.


How variables flow

Docker Compose path

.env (repo root)
   │
   ├─► docker-compose.yml ${VAR} substitution
   │
   └─► backend container environment
          │
          └─► pydantic Settings in backend/app/config.py

Compose loads the root .env for ${VAR} substitution in the compose file automatically. The backend service also mounts .env via env_file when the file exists (required: false — stack starts without it).

Compose env var Backend setting Default if unset
DATABASE_URL database_url postgresql+psycopg://urmi:urmi@postgres:5432/urmi
FRONTEND_ORIGIN frontend_origin http://localhost:5173
AUTH_SECRET auth_secret urmi-local-development-secret-change-me
AUTH_COOKIE_SECURE auth_cookie_secure false
GOOGLE_CLIENT_ID google_client_id empty
GOOGLE_CLIENT_SECRET google_client_secret empty
GOOGLE_REDIRECT_URI google_redirect_uri http://localhost:8000/api/v1/auth/google/callback
ULTRONSMS_BASE_URL ultronsms_base_url https://ultronsms.com
ULTRONSMS_USER ultronsms_user empty
ULTRONSMS_PASSWORD ultronsms_password empty

Frontend in Compose:

Compose env var Used by Default
VITE_API_URL frontend/src/lib/api.ts http://localhost:8000

Postgres in Compose (not read by backend config today — fixed in compose):

Compose env var Value
POSTGRES_DB urmi
POSTGRES_USER urmi
POSTGRES_PASSWORD urmi

Host port mapping: Postgres is exposed on 5433 (not 5432) to avoid clashing with a local Postgres install.

Local backend path (no Docker for API)

backend/.env  ──or──  ../.env (repo root)
        │
        └─► pydantic Settings (backend/app/config.py)

When running from backend/:

uvicorn app.main:app --reload

Settings are loaded from environment variables. Pydantic also reads:

  1. backend/.env
  2. ../.env (repo root)

Important: Use host port 5433 in DATABASE_URL when Postgres runs via Compose but the API runs on the host:

DATABASE_URL=postgresql+psycopg://urmi:urmi@localhost:5433/urmi

Inside the backend container, use the internal service name and port 5432:

DATABASE_URL=postgresql+psycopg://urmi:urmi@postgres:5432/urmi

Local frontend path (no Docker for UI)

frontend/.env
   │
   └─► VITE_API_URL ──► import.meta.env.VITE_API_URL

Vite bakes VITE_* variables at dev/build time. Restart the dev server after changing frontend/.env.


Backend variables (reference)

Defined in backend/app/config.py.

Variable Required Default Notes
APP_NAME No Urmi API OpenAPI title
ENVIRONMENT No development Informational
DATABASE_URL Yes* localhost URL *Required for real DB access
FRONTEND_ORIGIN Yes http://localhost:5173 CORS + OAuth redirect target
AUTH_SECRET Yes in prod weak dev default Signs session JWT cookies
AUTH_COOKIE_SECURE No false Set true when served over HTTPS
ACCESS_TOKEN_MINUTES No 10080 (7 days) Session lifetime
GOOGLE_CLIENT_ID For Google login empty OAuth client ID
GOOGLE_CLIENT_SECRET For Google login empty OAuth client secret
GOOGLE_REDIRECT_URI For Google login localhost callback Must match Google Console

Pydantic accepts both SCREAMING_SNAKE env names and lowercase field names.


Frontend variables (reference)

Variable Required Default Notes
VITE_API_URL No http://localhost:8000 All API calls + Google OAuth start URL

Authentication env checklist

Email / password only (works out of the box)

  • Copy .env.example → .env at repo root (Compose) or backend/.env.example → backend/.env (local API)
  • Set a strong AUTH_SECRET before any shared/staging deploy
  • Ensure FRONTEND_ORIGIN matches the URL you open in the browser

Google sign-in

  • Create a Web application OAuth client in Google Cloud Console

  • Authorized redirect URI:

    http://localhost:8000/api/v1/auth/google/callback
    
  • Set in .env / backend/.env:

    GOOGLE_CLIENT_ID=...
    GOOGLE_CLIENT_SECRET=...
    GOOGLE_REDIRECT_URI=http://localhost:8000/api/v1/auth/google/callback
    
  • Restart backend after changing auth env vars

  • FRONTEND_ORIGIN must match where users land after OAuth (default http://localhost:5173)

If Google vars are empty, the Continue with Google button returns 503 Google sign-in is not configured.


Infrastructure services (Compose)

These are configured in docker-compose.yml today. The backend does not consume them yet — documented here for when they are wired.

Service Profile Key env Host ports
Postgres core POSTGRES_* 5433 → 5432
Redis core none 6379
Kafka data-plane KAFKA_CFG_* 9092
ClickHouse analytics none 8123, 9000
MinIO object-storage MINIO_ROOT_USER, MINIO_ROOT_PASSWORD 9001, 9002

Start optional profiles:

docker compose --profile data-plane --profile analytics --profile object-storage up

Planned backend env (not implemented yet)

Variable Purpose
REDIS_URL Rate limits, OTP state, cache
KAFKA_BOOTSTRAP_SERVERS Event bus
CLICKHOUSE_URL Analytics ingest
S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY, S3_BUCKET Object storage (MinIO locally)

Production notes

  1. Never commit .env — only .env.example templates.
  2. Rotate AUTH_SECRET — invalidates all sessions when changed.
  3. Set AUTH_COOKIE_SECURE=true behind HTTPS.
  4. Use strong Postgres credentials — replace compose defaults.
  5. Update FRONTEND_ORIGIN and GOOGLE_REDIRECT_URI for your production domain.
  6. Frontend build: pass VITE_API_URL at build time for production API host.

Troubleshooting

Symptom Likely cause Fix
/api/v1/auth/me 401 after login Cookie not sent Same-site: frontend and API origins must work with credentials: 'include'; check CORS FRONTEND_ORIGIN
Google button 503 Missing OAuth vars Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET, restart backend
Google redirect error Redirect URI mismatch Match GOOGLE_REDIRECT_URI exactly in Google Console
Backend can't connect to DB (local API) Wrong host/port Use localhost:5433 when Postgres runs in Docker
Backend can't connect to DB (container) Wrong host Use postgres:5432, not localhost
Frontend calls wrong API Stale Vite env Set VITE_API_URL in frontend/.env, restart npm run dev
Changes to root .env ignored Compose not restarted docker compose up -d --build backend

Maintenance log

Date Change
2026-08-30 Initial env doc; added backend/.env.example, frontend/.env.example; expanded root .env.example

When adding new env-dependent features, update:

  1. backend/app/config.py (or relevant service config)
  2. Matching .env.example file(s)
  3. docker-compose.yml if Compose should pass the variable
  4. This document