Configuration reference¶
Repod is configured through two files: .env (Docker Compose variables) and backend.env (backend application settings). This page documents every available option.
.env — Docker Compose variables¶
These variables control how the containers are built and exposed.
| Variable | Default | Description |
|---|---|---|
BIND_HOST |
0.0.0.0 |
IP address Docker binds container ports to. Set to 127.0.0.1 if behind a reverse proxy on the same host. |
APT_PORT |
80 |
Host port for the APT repository (Nginx serving packages). |
BACKEND_PORT |
8000 |
Host port for the FastAPI backend. |
FRONTEND_PORT |
3003 |
Host port for the React web UI. |
REACT_APP_API_URL |
http://localhost:8000 |
URL the browser uses to call the backend API. Must be reachable from the user's browser — update to your public URL when using a reverse proxy. |
REACT_APP_REPO_URL |
http://localhost:80 |
URL the browser uses to display APT repo URLs to users. |
BIND_HOST in production
If you expose Repod directly (no reverse proxy), keep BIND_HOST=0.0.0.0. If you run a reverse proxy on the same host, set BIND_HOST=127.0.0.1 to prevent direct access to backend ports. See Reverse proxy guide.
backend.env — Application settings¶
Authentication¶
| Variable | Required | Description |
|---|---|---|
JWT_SECRET_KEY |
✅ | HS256 signing secret for JWT tokens. Generate with openssl rand -hex 32. The application refuses to start in production if this is the default value. |
JWT_ALGORITHM |
— | JWT algorithm. Default: HS256. Do not change unless you know what you're doing. |
ACCESS_TOKEN_EXPIRE_MINUTES |
— | JWT token lifetime in minutes. Default: 60. |
Initial admin account¶
| Variable | Required | Description |
|---|---|---|
ADMIN_USERNAME |
— | Admin account username. Default: admin. |
ADMIN_PASSWORD_HASH |
✅ | bcrypt hash of the admin password. Generate: docker run --rm python:3.11-slim python -c "from passlib.hash import bcrypt; print(bcrypt.hash('YourPass1!'))". Escape $ as $$ in .env files. |
Environment mode¶
| Variable | Default | Description |
|---|---|---|
ENV |
production |
Set to development to enable Swagger UI (/docs), hot-reload, and relaxed proxy trust. Never set to development in production. |
Paths (pre-configured via Docker volumes — do not change)¶
| Variable | Value | Description |
|---|---|---|
POOL_DIR |
/repos/pool |
Directory where .deb files are stored |
MANIFEST_DIR |
/repos/manifests |
Package manifest JSONs |
STAGING_INCOMING |
/repos/staging/incoming |
Upload landing zone |
STAGING_QUARANTINE |
/repos/staging/quarantine |
Quarantined packages |
AUDIT_DIR |
/repos/audit |
Audit log JSONL files |
INDEX_DIR |
/repos/package-index |
Synced APT source indexes |
IMPORTS_DIR |
/repos/imports |
Imported package groups |
AUTH_DB_PATH |
/repos/auth/users.db |
SQLite user database |
SETTINGS_PATH |
/repos/settings.json |
Application settings file |
SECURITY_DIR |
/repos/security |
Security-related data |
GNUPG_HOME |
/repos/gnupg |
GPG keyring shared with apt-repo container |
NGINX_LOGS_DIR |
/repos/logs |
Nginx access logs (for download stats) |
CLAMAV_DB_DIR |
/var/lib/clamav |
ClamAV signature database |
GRYPE_DB_CACHE_DIR |
/repos/grype-db |
Grype vulnerability database cache |
ADD_DEB_SCRIPT |
/scripts/add-deb.sh |
Script called by backend to index new packages |
INDEX_PATH |
/repos/manifests/index.json |
Package index file |
Network & proxy¶
| Variable | Default | Description |
|---|---|---|
TRUSTED_PROXIES |
127.0.0.1,172.16.0.0/12,192.168.0.0/16 |
Comma-separated list of trusted reverse proxy IPs or CIDR ranges. Used by uvicorn --forwarded-allow-ips to trust X-Forwarded-For headers. |
SMTP (email notifications)¶
Configured via the web UI (Settings → Email) and stored in settings.json. Not set via environment variables.
LDAP¶
Configured via the web UI (Settings → LDAP) and stored in settings.json. See Configure LDAP.
settings.json — Runtime configuration¶
The file at /repos/settings.json (mounted volume) stores runtime settings modified through the web UI. It is read at startup and updated when you save changes in the UI.
Info
You can edit settings.json directly as a text file if the web UI is unavailable. Restart the backend container after manual edits: docker compose restart backend.
Key sections¶
{
"sync": {
"enabled": true,
"hour": 3,
"minute": 0
},
"cve_policy": {
"critical": "review",
"high": "review",
"medium": "warn",
"low": "allow",
"sla_critical_days": 0,
"sla_high_days": 30,
"sla_medium_days": 90,
"epss_enrichment": true,
"kev_enrichment": true
},
"validation": {
"clamav_enabled": true,
"grype_enabled": true,
"max_upload_size_mb": 500
},
"retention": {
"audit_days": 90,
"imports_days": 30
},
"notifications": {
"webhook_url": "",
"smtp_host": "",
"smtp_port": 587,
"smtp_user": "",
"smtp_password": "***",
"smtp_from": "",
"smtp_to": "",
"smtp_tls": true
},
"ldap": {
"enabled": false,
"host": "",
"port": 389,
"use_ssl": false,
"use_tls": false,
"verify_cert": true,
"ca_bundle_path": "",
"bind_dn": "",
"bind_password": "***",
"base_dn": "",
"user_filter": "(objectClass=person)",
"username_attr": "uid",
"email_attr": "mail",
"group_mappings": [],
"auto_provision": true
}
}
Resource limits (Docker Compose)¶
The backend container has default resource limits:
Increase these for large repositories or high upload throughput. Grype and ClamAV scans are CPU-intensive.
Environment: production vs. development¶
| Behaviour | ENV=production |
ENV=development |
|---|---|---|
Swagger UI (/docs) |
❌ 404 | ✅ enabled |
| uvicorn workers | 2 | 1 |
Hot-reload (--reload) |
❌ | ✅ |
| JWT secret validation | ✅ crash if default | ⚠️ warning only |
| Proxy trust | TRUSTED_PROXIES list |
* (all) |
| Source code mount | ❌ | ✅ (./backend:/app) |
| Docker socket | ❌ | ✅ (for GPG dev workflow) |
To run in development mode: