Configuration

All configuration is done via environment variables in .env.

Required Variables

Variable Description
POSTGRES_PASSWORD Database password. Use a strong random value.
JWT_SECRET JWT signing secret. At least 32 random characters.

Backend Variables

Variable Default Description
DATABASE_URL auto-generated PostgreSQL connection string. Auto-set from POSTGRES_* vars in Docker.
DEFAULT_ADMIN_EMAIL admin@aberon.internal Admin login email, created on first startup.
DEFAULT_ADMIN_PASSWORD (auto-generated) Admin password. If empty, a random password is printed in backend logs.
JWT_SECRET_PREVIOUS (empty) Previous JWT secret for key rotation. Set when rotating JWT_SECRET.
LOG_LEVEL info Logging level: debug, info, warning, error.
WORKERS 2 Number of uvicorn worker processes.
RATE_LIMIT_PER_MINUTE 600 Max API requests per minute per IP.

Data Retention

Variable Default Description
TRACE_RETENTION_DAYS 30 Traces older than this are auto-deleted.
AUDIT_RETENTION_DAYS 365 Audit log entries older than this are auto-deleted.
APPROVAL_RETENTION_DAYS 90 Approval records older than this are auto-deleted.

Approvals

Variable Default Description
APPROVAL_TIMEOUT_SECONDS 300 Default timeout for approval requests (5 minutes).

License

Variable Default Description
LICENSE_FILE /app/license.key Path to license file inside the container. See how license files work.
LICENSE_ENFORCE false Legacy setting. Freemium model always allows startup.

Demo

Variable Default Description
SEED_DEMO false Set to true to pre-populate demo data on first startup. See Demo Mode.

Networking

Variable Default Description
PORT 3000 External port for the gateway (nginx). This is the only port you need.

Architecture

docker compose up -d starts 4 containers:

┌─────────────────────────────────────────────────┐
│              Gateway (nginx:alpine)              │
│              Port 3000 (configurable)            │
│                                                  │
│  /api/*  ──→  backend:8080                       │
│  /health ──→  backend:8080                       │
│  /*      ──→  frontend:3000                      │
└─────────────────────────────────────────────────┘
           │                    │
    ┌──────┴──────┐     ┌──────┴──────┐
    │   Backend   │     │  Frontend   │
    │  (FastAPI)  │     │  (Next.js)  │
    │  port 8080  │     │  port 3000  │
    │  internal   │     │  internal   │
    └──────┬──────┘     └─────────────┘
           │
    ┌──────┴──────┐
    │  PostgreSQL │
    │  port 5432  │
    │  internal   │
    └─────────────┘

Only the gateway port is exposed externally. Backend, frontend, and PostgreSQL communicate on an internal Docker network.

Backup & Restore

Backup

docker compose exec postgres pg_dump -U aberon aberon | gzip > backup-$(date +%Y%m%d).sql.gz

Restore

docker compose down
docker compose up -d postgres
# Wait for postgres to be healthy, then:
gunzip -c backup.sql.gz | docker compose exec -T postgres psql -U aberon aberon
docker compose up -d

Updating to a New Version

Your data is safe — it lives in a Docker volume. Migrations run automatically on startup.

# 1. Backup
docker compose exec postgres pg_dump -U aberon aberon | gzip > backup.sql.gz

# 2. Stop
docker compose down

# 3. Load new images (include gateway/nginx — easy to forget)
docker load < aberon-backend.tar.gz
docker load < aberon-frontend.tar.gz
docker load < nginx-alpine.tar.gz
# Or: for f in *.tar.gz; do docker load < "$f"; done

# 4. Start (migrations apply automatically)
docker compose up -d

# 5. Verify
docker compose logs backend | tail -20

Your .env, license.key, and database volume are preserved across updates.