Configuration Reference
Contract Lucidity is configured via environment variables. The backend reads these through Pydantic's BaseSettings class, which supports both environment variables and a .env file at the project root.
All variables are case-insensitive (e.g., POSTGRES_USER and postgres_user are equivalent).
Database
| Variable | Default | Description | Service |
|---|---|---|---|
POSTGRES_USER | cl_user | PostgreSQL username | cl-backend, cl-worker, cl-db |
POSTGRES_PASSWORD | cl_password_change_me | PostgreSQL password | cl-backend, cl-worker, cl-db |
POSTGRES_DB | contract_lucidity | PostgreSQL database name | cl-backend, cl-worker, cl-db |
POSTGRES_HOST | cl-postgres | PostgreSQL hostname | cl-backend, cl-worker |
POSTGRES_PORT | 5432 | PostgreSQL port | cl-backend, cl-worker |
The default PostgreSQL password is cl_password_change_me. Always set a strong, unique password in production via POSTGRES_PASSWORD.
The database connection URLs are derived automatically:
- Async (backend API):
postgresql+asyncpg://{user}:{password}@{host}:{port}/{db} - Sync (Celery worker):
postgresql+psycopg2://{user}:{password}@{host}:{port}/{db}
Redis / Celery
| Variable | Default | Description | Service |
|---|---|---|---|
REDIS_HOST | cl-redis | Redis hostname | cl-backend, cl-worker |
REDIS_PORT | 6379 | Redis port | cl-backend, cl-worker |
REDIS_URL | redis://cl-redis:6379/0 | Full Redis URL | cl-backend, cl-worker |
CELERY_BROKER_URL | redis://cl-redis:6379/0 | Celery broker URL (Redis db 0) | cl-worker |
CELERY_RESULT_BACKEND | redis://cl-redis:6379/1 | Celery result backend (Redis db 1) | cl-worker |
JWT / Authentication
| Variable | Default | Description | Service |
|---|---|---|---|
JWT_SECRET_KEY | change-me-to-a-random-secret-in-production | Secret key for signing JWT tokens | cl-backend |
JWT_ALGORITHM | HS256 | JWT signing algorithm | cl-backend |
JWT_ACCESS_TOKEN_EXPIRE_MINUTES | 60 | Access token lifetime in minutes | cl-backend |
JWT_REFRESH_TOKEN_EXPIRE_DAYS | 7 | Refresh token lifetime in days | cl-backend |
The default JWT secret is a placeholder. In production, generate a random 64+ character secret:
openssl rand -hex 64
Application
| Variable | Default | Description | Service |
|---|---|---|---|
APP_NAME | Contract Lucidity | Application display name | cl-backend |
APP_ENV | development | Environment identifier (development, staging, production) | cl-backend |
LOG_LEVEL | INFO | Logging level (DEBUG, INFO, WARNING, ERROR) | cl-backend, cl-worker |
MAX_UPLOAD_SIZE_MB | 100 | Maximum file upload size in megabytes | cl-backend |
Storage
| Variable | Default | Description | Service |
|---|---|---|---|
STORAGE_PATH | /data/storage | Path for uploaded document files | cl-backend, cl-worker |
CONFIG_PATH | /data/config | Path for application configuration files | cl-backend, cl-worker |
These paths correspond to Docker volumes cl-storage and cl-config. If running without Docker, ensure these directories exist and are writable.
CORS and URLs
| Variable | Default | Description | Service |
|---|---|---|---|
CORS_ORIGINS | http://localhost:3000,https://contractlucidity.com | Comma-separated list of allowed CORS origins | cl-backend |
FRONTEND_URL | http://localhost:3000 | Public URL of the frontend (used for links in emails, etc.) | cl-backend |
BACKEND_INTERNAL_URL | http://cl-backend:8000 | Internal URL for frontend-to-backend communication | cl-frontend |
For production, set CORS_ORIGINS to include your domain:
CORS_ORIGINS=https://contracts.yourcompany.com
The frontend uses BACKEND_INTERNAL_URL to proxy API requests within the Docker network. This should remain as the default unless you have a custom network topology.
Default Admin
| Variable | Default | Description | Service |
|---|---|---|---|
DEFAULT_ADMIN_EMAIL | [email protected] | Email for the auto-created admin account | cl-backend |
DEFAULT_ADMIN_PASSWORD | <your-strong-password> | Initial password for the admin account | cl-backend |
The default admin is created on first boot during the seed process. The account is flagged with must_change_password=True, prompting a password change on first login.
Change DEFAULT_ADMIN_PASSWORD before first boot in production, or change the password immediately after first login. The seed process will not overwrite an existing admin account.
Frontend-Specific
These variables are set on the cl-frontend service in Docker Compose:
| Variable | Default | Description | Service |
|---|---|---|---|
BACKEND_INTERNAL_URL | http://cl-backend:8000 | Backend API URL used by the Next.js server-side proxy | cl-frontend |
NEXT_PUBLIC_FRONTEND_URL | http://localhost:3000 | Public-facing frontend URL (available client-side) | cl-frontend |
NEXT_PUBLIC_ prefixed variables are embedded at build time in Next.js and available in the browser. BACKEND_INTERNAL_URL is server-side only and never exposed to the client.
Worker-Specific
| Variable | Default | Description | Service |
|---|---|---|---|
CELERY_CONCURRENCY | 2 | Number of parallel Celery worker processes | cl-worker |
Each concurrency slot processes one document at a time and makes multiple AI API calls. Higher concurrency means faster throughput but more memory usage and higher AI API costs. Recommended values:
- Development: 1-2
- Small team: 2-4
- Production: 4-8 (depending on available RAM and AI API rate limits)
Allow approximately 512 MB - 1 GB of RAM per concurrency slot.
Complete .env Example
# Database
POSTGRES_USER=cl_user
POSTGRES_PASSWORD=your-strong-database-password
POSTGRES_DB=contract_lucidity
# Redis
REDIS_URL=redis://cl-redis:6379/0
# Authentication
JWT_SECRET_KEY=your-64-character-random-secret-here
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=60
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
# Application
APP_ENV=production
LOG_LEVEL=INFO
MAX_UPLOAD_SIZE_MB=100
# CORS / URLs
CORS_ORIGINS=https://contracts.yourcompany.com
FRONTEND_URL=https://contracts.yourcompany.com
BACKEND_INTERNAL_URL=http://cl-backend:8000
# Admin
DEFAULT_ADMIN_EMAIL=[email protected]
DEFAULT_ADMIN_PASSWORD=initial-strong-password
# Worker
CELERY_CONCURRENCY=4
Never commit .env files to version control. Add .env to your .gitignore.