first commit
This commit is contained in:
commit
efa5080897
127 changed files with 18610 additions and 0 deletions
260
docs/ENVIRONMENT.md
Normal file
260
docs/ENVIRONMENT.md
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
# Urmi environment configuration
|
||||
|
||||
This document tracks every environment variable, where it lives, and how it flows through local development and Docker.
|
||||
|
||||
## Quick start
|
||||
|
||||
### Docker Compose (recommended)
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```text
|
||||
.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)
|
||||
|
||||
```text
|
||||
backend/.env ──or── ../.env (repo root)
|
||||
│
|
||||
└─► pydantic Settings (backend/app/config.py)
|
||||
```
|
||||
|
||||
When running from `backend/`:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```text
|
||||
DATABASE_URL=postgresql+psycopg://urmi:urmi@localhost:5433/urmi
|
||||
```
|
||||
|
||||
Inside the backend container, use the internal service name and port 5432:
|
||||
|
||||
```text
|
||||
DATABASE_URL=postgresql+psycopg://urmi:urmi@postgres:5432/urmi
|
||||
```
|
||||
|
||||
### Local frontend path (no Docker for UI)
|
||||
|
||||
```text
|
||||
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](https://console.cloud.google.com/apis/credentials)
|
||||
- [ ] Authorized redirect URI:
|
||||
|
||||
```text
|
||||
http://localhost:8000/api/v1/auth/google/callback
|
||||
```
|
||||
|
||||
- [ ] Set in `.env` / `backend/.env`:
|
||||
|
||||
```text
|
||||
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:
|
||||
|
||||
```bash
|
||||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue