Configuration

Everything is configured with environment variables — no config file to maintain. Values below are the defaults compiled into the binary; set them on the container, in your compose file, or in your platform's environment tab.

AUTH_PASS is mandatory. The server logs an error and exits on start-up without it. Set ALLOW_NO_AUTH=true only for local testing (make run already does this).

Core

VariableDefaultMeaning
LISTEN:8080HTTP listen address.
DB_PATH/data/capscope.dbSQLite file — must be on a persistent volume.
DOCKER_HOSTunix:///var/run/docker.sockunix:// socket or tcp://host:port for a socket proxy.
AUTH_USER / AUTH_PASSadmin / noneHTTP Basic auth. The server refuses to start without AUTH_PASS.
ALLOW_NO_AUTHfalseRun without auth. Local testing only.
LOG_LEVELinfodebug, info, warn, error — CapScope's own logs.

Retention and size

Durations accept d, h and m suffixes (for example 7d, 12h, 30m). Retention is enforced 30 seconds after start and then every 10 minutes, deleting in batches of 5000 rows so write locks stay short.

VariableDefaultMeaning
LOG_RETENTION7dDelete log rows older than this.
METRICS_RETENTION7dSame for CPU/memory samples.
SNAPSHOT_RETENTION30dSame for crash snapshots.
MAX_DB_MB1024Hard cap on database size. Oldest data is dropped first: logs, then metrics, then access, then snapshots, alerts and deploys.
APP_RETENTIONnonePer-app retention, comma separated: web=3d,api=1d. Applied before the global cap.
APP_MAX_MBnonePer-app byte budget: web=500,api=200. Trims one noisy app before the whole database is squeezed.
MAX_DB_MB wins over LOG_RETENTION. If your volume is high, the oldest logs are dropped early to stay under the cap. Raise the cap, shorten retention, or use EXCLUDE for chatty containers such as your proxy.

Collection

VariableDefaultMeaning
STATS_INTERVAL10sMetric sample interval per container. Minimum 1s.
INITIAL_TAIL200Lines backfilled the first time a container is seen.
MAX_LINE_BYTES16384Lines longer than this are truncated.
REDACTtrueMask secrets before storage (JWTs, bearer tokens, password=, URL credentials, AWS keys, PEM keys).
INCLUDE / EXCLUDEnoneRegexes matched against container and app names. EXCLUDEed containers are still followed for access logs only.
SNAPSHOT_KINDScrash,oomWhich stop kinds create snapshots: crash, oom, killed, clean_exit.
SNAPSHOT_LOG_LINES200Log lines stored per crash snapshot.
RESTART_LOOP_COUNT3Deaths inside the window required to flag a restart loop.
RESTART_LOOP_WINDOW5mSliding window used for restart-loop detection.

Access logs

VariableDefaultMeaning
ACCESS_LOGautoauto detects reverse-proxy containers and switches on when most recent stdout parses as access logs; all parses everything; off disables it.
ANON_IPStrueAnonymize client IPs (last octet zeroed for IPv4, IPv6 cut to /48). Set false to store originals.

Access rows follow LOG_RETENTION. Supported formats: nginx combined/common, CapRover's captain-nginx default, and most proxy defaults.

Alerting

VariableDefaultMeaning
ALERTS_FILE/data/alerts.jsonJSON rules file, hot-reloaded when its mtime changes — editing it needs no restart.
ALERTS_INTERVAL1mHow often rules are evaluated.
ALERT_WEBHOOK_URLnoneGeneric JSON webhook.
ALERT_TELEGRAM_TOKEN / ALERT_TELEGRAM_CHAT_IDnoneTelegram Bot API.
ALERT_SLACK_URLnoneSlack incoming webhook.
ALERT_DISCORD_URLnoneDiscord webhook.

Channels are best-effort: a failing webhook is logged and the next channel still runs. Verify with Send test alert in the UI, or POST /api/alerts/test. Full rule syntax on the alert rules page.

Sizing the database

Measured on a sandbox: about 400 bytes of database per stored log line for 130-byte lines (three indexes included).

estimate
bytes per day = lines per second x 86400 x 400
Lines per second (all apps)Per dayPer 7 days
1about 35 MBabout 240 MB
10about 350 MBabout 2.4 GB
100about 3.5 GBabout 24 GB

Metrics are cheap: one row per container every 10 seconds is about 8,600 rows per container per day.

Full example

docker-compose.yml
services:
  capscope:
    image: ghcr.io/hacrex/capscope:latest
    ports: ["8080:8080"]
    environment:
      AUTH_USER: admin
      AUTH_PASS: "${CAPSCOPE_PASS:?required}"
      MAX_DB_MB: 2048
      LOG_RETENTION: 14d
      SNAPSHOT_RETENTION: 90d
      EXCLUDE: "^captain-|^traefik"
      APP_RETENTION: web=3d,api=1d
      ALERTS_FILE: /data/alerts.json
    volumes:
      - capscope-data:/data
      - ./alerts.json:/data/alerts.json:ro
      - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped

volumes:
  capscope-data:
Never scale beyond one replica. Two CapScope instances writing the same SQLite file will corrupt your history. The container runs as root on purpose — the Docker socket requires it.