oxid/ docs

// daemon

Environment variables

All configuration is environment-based — no config file for the daemon itself.

VariableDefaultDescription
OXID_DATA_DIR/dataState directory: audit.sqlite, git-cache/, secret.key.
OXID_ADDR0.0.0.0:8080Bind address.
OXID_GC_INTERVAL_SECS30Scheduler tick for GC / deploy-queue retries.
OXID_MASTER_KEYgenerated64-hex master key for secret encryption; generated + persisted to secret.key (0600) when unset.
OXID_API_TOKENunsetBearer token required on /api/v1/*. Unset = open API (fine on localhost) — or set OXID_AUTO_TOKEN=1 to auto-generate and persist it (printed once to logs).
OXID_ALLOW_OPEN_API01 to let a non-loopback daemon start without OXID_API_TOKEN (explicit opt-in to an unauthenticated API).
OXID_AUTO_TOKEN01 for zero-config starts: any of OXID_API_TOKEN / OXID_WEBHOOK_SECRET not set is generated (64 hex), persisted under {data}/ (0600) and printed once — the shipped docker-compose.yml uses this so docker compose up -d works with no .env.
OXID_WEBHOOK_SECRETunsetHMAC-SHA256 secret for GitHub/GitLab/Gitea/Gogs webhooks; webhooks rejected while unset (or auto-generated with OXID_AUTO_TOKEN=1).
OXID_DOCKER_NETWORKunsetShared network with Traefik: containers get subdomains instead of host ports, and scale-to-zero wake-on-request activates. The wizard's infra step bootstraps this with one click (POST /api/v1/infra/bootstrap).
OXID_DAEMON_URLhttp://oxid-daemon:8080The daemon's own address inside OXID_DOCKER_NETWORK (Traefik forwardAuth labels).
OXID_POSTGRES_URLunsetAdmin connection string for a shared Postgres — per-branch logical databases for projects declaring the dependency.
OXID_REDIS_URLunsetBase URL of a shared Redis; per-branch logical databases.
OXID_REDIS_POOL_SIZE16Leasable Redis logical databases.
OXID_DEFAULT_MEMORY_LIMIT_MB512Fallback container memory limit; 0 disables.
OXID_DEFAULT_CPU_LIMIT_MILLICORES1000Fallback container CPU limit; 0 disables.
OXID_RESERVED_MEMORY_MB1024Host memory reserved before admission control starts queueing deploys; 0 disables queueing.
OXID_TLS_CERT / OXID_TLS_KEYunsetPEM paths — when both are set the daemon serves HTTPS directly.
OXID_ALLOW_RESTORE01 to accept POST /api/v1/backup/restore uploads at all (staged, applied on next restart).
OXID_BACKUP_INTERVAL_SECSunsetWhen set (e.g. 300), periodic VACUUM INTO snapshots to {data}/backups/.
OXID_BACKUP_KEEP7Newest snapshots to keep when backups are enabled.
OXID_RATE_LIMIT_PER_SECOND / _BURSTunsetWhen both are set, token-bucket rate limit on protected routes (per client IP).
RUST_LOGinfoTracing filter, e.g. oxid_daemon=debug,info.
OXID_LOG_FORMATprettypretty or json (one object per line — use in production).

On startup the daemon reconciles its database against Docker's actual state before serving any request, and drains in-flight requests for up to 10s on SIGTERM/Ctrl+C instead of dying mid-request.

Data layout

Everything lives under OXID_DATA_DIR — back this up (or use oxid backup) and you have the whole system.

/data
├── audit.sqlite      # all state + audit trail (WAL mode)
├── secret.key        # AES-GCM master key, mode 0600
├── api-token         # auto-generated when OXID_AUTO_TOKEN=1 (0600)
├── webhook-secret    # auto-generated when OXID_AUTO_TOKEN=1 (0600)
├── git-cache/        # cached clones, one dir per project
└── backups/          # VACUUM INTO snapshots when OXID_BACKUP_INTERVAL_SECS is set

A restore never touches the live database in place — an upload is staged and applied on the next daemon startup.