Configuration
Environment variables, service tuning, and secret handling for a self-hosted ATHELOS.
Configuration
This page covers how to configure a self-hosted ATHELOS — which environment variables matter, how to tune services, and how to handle secrets.
The three env files
ATHELOS reads configuration from three files:
| File | Used by |
|---|---|
.env | Scripts and Drizzle Kit (repo root) |
apps/web/.env.local | The web application at runtime |
docker/.env | Docker Compose services |
Each has an .example template. Copy and fill in real values.
Root .env
Used by scripts that run outside the web app — database migrations, seeds, and maintenance tasks.
| Variable | Purpose |
|---|---|
DATABASE_URL | Postgres connection string |
REDIS_URL | Redis connection string |
MEILI_HOST | Meilisearch HTTP endpoint |
MEILI_MASTER_KEY | Meilisearch admin key |
AUTH_SECRET | Session signing secret |
apps/web/.env.local
The full runtime config for the web app.
Required
| Variable | Purpose |
|---|---|
DATABASE_URL | Postgres connection string |
AUTH_SECRET | Session signing key — write-once |
AUTH_TRUST_HOST | Set true for local dev behind a proxy |
NEXTAUTH_URL | Public URL of the app |
REDIS_URL | Redis connection string |
MEILI_HOST | Meilisearch HTTP endpoint |
MEILI_MASTER_KEY | Meilisearch admin key |
MINIO_ENDPOINT | MinIO hostname |
MINIO_PORT | MinIO port |
MINIO_USE_SSL | false locally, true in production |
MINIO_ACCESS_KEY | MinIO access key |
MINIO_SECRET_KEY | MinIO secret key |
MINIO_BUCKET | Bucket for evidence files |
TOTP_ENCRYPTION_KEY | AES-256-GCM key for TOTP secrets — write-once |
Optional — AI
| Variable | Default |
|---|---|
OLLAMA_HOST | http://localhost:11434 |
OLLAMA_MODEL | llama3.2:3b |
OLLAMA_NUM_CTX | 2048 |
OLLAMA_EMBED_MODEL | nomic-embed-text |
Optional — WebAuthn
| Variable | Purpose |
|---|---|
WEBAUTHN_RP_ID | Relying Party ID — the domain |
WEBAUTHN_RP_NAME | Display name shown in browser prompts |
WEBAUTHN_ORIGIN | The origin (e.g. https://athelos.example.com) |
Optional — SMTP
| Variable | Purpose |
|---|---|
SMTP_HOST | Mail server |
SMTP_PORT | Port (587 or 465) |
SMTP_USER | Login |
SMTP_PASSWORD | Password |
SMTP_FROM | From address |
SMTP_TO | Destination address |
SMTP_SECURE | true for implicit TLS |
Optional — Webhooks
| Variable | Purpose |
|---|---|
WEBHOOK_URL | Endpoint to POST notifications to |
WEBHOOK_SECRET | HMAC signing secret |
docker/.env
Used by Docker Compose.
| Variable | Purpose |
|---|---|
POSTGRES_PASSWORD | Postgres password for the soc user |
REDIS_PASSWORD | Redis AUTH password |
MINIO_ROOT_USER | MinIO admin username |
MINIO_ROOT_PASSWORD | MinIO admin password |
MEILI_MASTER_KEY | Meilisearch admin key |
Important: values here must match the corresponding values in
apps/web/.env.local. The app needs the passwords to connect.
Write-once secrets
Three secrets must never change after first use:
| Secret | Consequence of changing |
|---|---|
AUTH_SECRET | All active sessions invalidated |
TOTP_ENCRYPTION_KEY | Existing TOTP secrets become undecryptable |
RESTIC_PASSWORD | Existing backup snapshots become unreadable |
Back each one up to a password manager and on paper. Never commit them. Never email them.
Generating strong values
For passwords and secrets:
openssl rand -base64 32For hex secrets:
openssl rand -hex 32Use a different random value for each variable. Never reuse.
Reloading after changes
Environment changes require a restart:
- Web app — kill and restart
pnpm devor the production service - Worker — kill and restart
- Docker services —
docker compose up -dre-readsdocker/.env
The web app doesn't hot-reload env changes.
Service tuning
Postgres
Default settings are fine for a single-operator install. If you process large
evidence files or run many concurrent queries, bump shared_buffers in
docker-compose.yml:
postgres:
command:
- postgres
- -c
- shared_buffers=512MB
- -c
- work_mem=16MBRedis
Redis is used for sessions, rate limits, and background jobs. Defaults are fine.
To change the max memory policy:
redis:
command:
- redis-server
- --maxmemory
- 256mb
- --maxmemory-policy
- allkeys-lruMinIO
MinIO has no meaningful configuration beyond its credentials. It stores what you give it.
Meilisearch
Meilisearch defaults are fine. To cap memory:
meilisearch:
environment:
MEILI_MAX_INDEXING_MEMORY: 512MbOllama (AI)
If you're running local AI, Ollama's memory usage depends on the model:
- 3B models — 4 GB RAM minimum
- 7B models — 8 GB recommended
- 13B models — 16 GB recommended
To reduce memory, use a smaller model or lower OLLAMA_NUM_CTX.
Secrets management
Never store secrets in git. Never email them. Never paste them in a chat.
Where secrets live:
.envfiles — chmod 600, gitignored- Password manager — the master copy
- Paper — offline backup for critical secrets
Where secrets do NOT live:
- Source code
- Config files in git
- Documentation
- Chat or email
To verify a file is gitignored:
git check-ignore -v apps/web/.env.localShould output the .gitignore rule that ignores it.
Rotation
Secrets should be rotated annually per best practice — but three secrets are write-once (see above). The others can be rotated:
- Postgres password — change in
docker/.env,apps/web/.env.local, and the running database - Redis password — change in
docker/.envandapps/web/.env.local - MinIO credentials — change in
docker/.envandapps/web/.env.local - Meilisearch key — change in
docker/.env,apps/web/.env.local, andapps/site/.env.local
After rotating, restart all services.
Production hardening
For a production install:
- Full-disk encryption (LUKS)
- SSH key-only, no password auth
- UFW firewall enabled
- Services bound to
127.0.0.1 -
.envfiles at 600 permissions - HTTPS via Caddy or a reverse proxy
- Access via VPN (Tailscale or WireGuard)
- No public exposure
- Backups tested
See Security for the full threat model and hardening checklist.
Where to go next
- Operations — updates, backups, maintenance
- Environment variables — the full reference
- Security — threat model and hardening