Skip to content

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

settings.json (structure)
{
  "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:

docker-compose.yaml (excerpt)
deploy:
  resources:
    limits:
      memory: 1g
      cpus: "1.5"

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:

docker compose -f docker-compose.yaml -f docker-compose.dev.yml up