Environment variables
Every service reads its own .env or is configured at build time.
apps/web
Build-time:
| Var | Required | Notes |
|---|---|---|
| NEXT_PUBLIC_API_URL | yes | Baked into the client bundle at build. Change → rebuild needed. |
Prod value: https://lumen-api.zenmail.my.id. Set via Docker build arg:
ARG NEXT_PUBLIC_API_URL=http://localhost:4000
ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
apps/api
Runtime:
| Var | Required | Default | Notes |
|---|---|---|---|
| PORT | no | 4000 | Listen port |
| DATABASE_URL | yes | — | Postgres connection string |
| REDIS_URL | yes | — | Redis for BullMQ |
| EMBEDDER_URL | yes | — | Embedder service base URL |
| JWT_SECRET | yes | — | HMAC key for JWT (use 32+ random bytes) |
| UPLOAD_DIR | no | /data/uploads | Document file storage |
| LLM_BASE_URL | no | — | Fallback LLM if no provider in DB |
| LLM_API_KEY | no | — | Fallback LLM key |
| LLM_MODEL | no | — | Fallback LLM model |
| TAVILY_API_KEY | no | — | Enables chat modes web and deep |
| NODE_ENV | no | development | Set to production in prod |
apps/embedder
| Var | Required | Default | Notes |
|---|---|---|---|
| MODEL_CACHE_DIR | no | /models | Where sentence-transformers caches weights |
apps/worker
| Var | Required | Notes |
|---|---|---|
| DATABASE_URL | yes | Same as API |
| REDIS_URL | yes | Same as API |
| EMBEDDER_URL | yes | Internal URL to embedder |
| UPLOAD_DIR | no | Shares volume with API |
Postgres container
| Var | Notes |
|---|---|
| POSTGRES_DB | lumen |
| POSTGRES_USER | lumen |
| POSTGRES_PASSWORD | Set via Dokploy env secret |
The init script at docker/init.sql runs once on a fresh DB:
- Enable
vectorextension - Create RLS policies (disabled on
chunks, enabled elsewhere)
Adding a new env var
- Add to
apps/api/.env.example(document the default) - Read via
process.env.FOOin code with a safe fallback - Update the Dockerfile if it needs to be build-time
- Update the Dokploy env in the web UI for prod
- Update this page
Secrets management
Dev phase: env values stored in Dokploy UI (encrypted at rest per Dokploy's scheme). No Vault / 1Password integration yet.
When we need secret rotation:
- Use Dokploy env scopes per stack
- Rotate
JWT_SECRETrequires re-login for all users (all tokens invalidate) - Rotate DB password requires updating
DATABASE_URLand rolling both API and worker