# ---- API ---- REDIS_HOST=redis REDIS_PORT=6379 REDIS_PASSWORD=change-me-strong-redis-password API_TOKEN=change-me-api-service-token MAX_SOURCE_SIZE=100000 MAX_STDIN_SIZE=100000 RATE_LIMIT_PER_MINUTE=120 MAX_QUEUED_PER_CLIENT=100 RESULT_TTL=86400 # seconds; result hashes expire (exam backend owns history) LOG_LEVEL=info LISTEN_PORT=8000 # ---- Worker ---- CPU_TIME_LIMIT=2 # seconds of CPU (cpu.stat usage_usec); SIGXCPU -> TLE WALL_TIME_LIMIT=10 # seconds; hard deadline (backstop >= 5x CPU_TIME_LIMIT) MEMORY_LIMIT=262144 # KB (256 MB); cgroup v2 memory.max PROCESS_LIMIT=64 # cgroup v2 pids.max (10 is too tight for Python threads) MAX_OUTPUT_SIZE=1048576 # bytes; stdout/stderr capture cap (output_limit_exceeded) MAX_FILE_SIZE=1048576 # bytes; rlimit_fsize per file (SIGXFSZ -> output_limit_exceeded) CPU_QUOTA_US=100000 # cgroup cpu.max quota (100000us = 1 CPU) CPU_PERIOD_US=100000 # cgroup cpu.max period LOCK_TTL_S=45 # execution lock TTL; MUST stay < CLAIM_IDLE_MS/1000 CLAIM_IDLE_MS=60000 # XAUTOCLAIM min-idle; MUST stay > LOCK_TTL_S MAX_ATTEMPTS=3 # execution attempts before dead-letter HEARTBEAT_INTERVAL_S=5 # Writable per-job run dir (tmpfs, 256m, mounted over the image dir) SANDBOX_ROOT=/sandbox # Leave empty to default to the container hostname WORKER_ID= # ---- Redis server (compose only) ---- # REDIS_PASSWORD above is shared by all services