Skip to content

Installation

Campfire ships as a single multi-arch Docker image. You need Docker (or any OCI runtime) and one persistent volume. That's it — SQLite and uploaded files both live under one data directory.

Quick start (Docker)

docker run -d --name campfire \
  -p 8080:8080 \
  -v campfire-data:/data \
  -e TZ=America/New_York \
  ghcr.io/awsomefox/campfire:latest

Open http://localhost:8080. The first visit shows “Light the fire” — create the initial administrator account, and you're in.

Runs as a non-root user

The container runs as the unprivileged node user (uid 1000), not root. A named Docker volume gets the right ownership automatically; if you bind-mount a host directory for /data, make sure uid 1000 can write to it (e.g. chown -R 1000:1000 <dir>).

That first account

The first user you create is the server admin. They can immediately run a campaign, or hand campaigns off to others — being the admin does not force you to be anyone's DM. See Roles & who does what.

Docker Compose

services:
  campfire:
    image: ghcr.io/awsomefox/campfire:latest
    container_name: campfire
    restart: unless-stopped
    init: true                       # graceful shutdown (PID 1 signal handling)
    environment:
      - TZ=America/New_York
      - NODE_ENV=production
      - PORT=8080
      - DATA_DIR=/data
    volumes:
      - /srv/campfire/data:/data     # SQLite db + uploads — back up this one path
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8080/readyz').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
      interval: 30s
      timeout: 10s
      retries: 3

Behind a reverse proxy (Traefik + SSO)

The SPA and API are served same-origin, so no CORS configuration is needed. Put Campfire behind Traefik (or any proxy) for TLS, and optionally in front of an identity provider. A homelab-style stack with Traefik labels and Authentik OIDC is documented in Authentication.

Configuration

Core

Variable Default Purpose
PORT 8080 HTTP port
DATA_DIR /data SQLite db + uploads (the one volume to back up)
TZ UTC Timezone for timestamps
ORIGIN (unset) Only needed if you split the SPA onto a different origin; leave unset for the single-image deployment
API_DOCS (unset) API docs (/api/docs, /api/openapi.json) are off in production by default; set 1 to enable them (or 0 to force them off)

Reverse proxy & rate limiting

Variable Default Purpose
TRUST_PROXY 1 (trust one hop) Express trust proxy setting. Pass a hop count if you sit behind more than one proxy (2, 3, …), false to disable, or an explicit IP/subnet allow-list. Needed so per-IP rate limiting and req.ip/req.secure see the real client IP behind a reverse proxy (Traefik in the reference deployment) rather than bucketing every request under the proxy's own address
THROTTLE_DISABLED (unset) Set to 1 to fully disable the built-in per-IP rate limiter. Intended for tests; leave unset in production
ALLOW_INSECURE_HTTP (unset) Set to 1 for a no-TLS LAN/homelab deployment reached over plain HTTP (e.g. http://192.168.1.x:8080). Drops the security headers that assume HTTPS — CSP upgrade-insecure-requests and HSTS — and issues the session cookie without the Secure attribute so login works. Leave unset whenever you have TLS; only enable it if you understand traffic is unencrypted

OIDC / SSO — see Authentication for the full table.

Variable Default Purpose
OIDC_ISSUER / OIDC_CLIENT_ID / OIDC_CLIENT_SECRET (unset) Enable SSO — all three must be set for OIDC to be considered enabled
OIDC_REDIRECT_URI (derived from APP_URL) OIDC callback URL, e.g. https://campfire.example.com/api/v1/auth/oidc/callback
OIDC_ADMIN_GROUP (unset) Members of this IdP group become server admins (synced on every login)
OIDC_ALLOWED_GROUP (unset) Restrict sign-in to members of this IdP group; others get a 403 and no account is provisioned
OIDC_GROUPS_CLAIM groups ID-token claim holding the user's group list
OIDC_SCOPE openid profile email Requested OAuth scopes
OIDC_ALLOW_INSECURE (unset) Allow OIDC over plain HTTP — dev/testing only, never in production
APP_URL http://localhost:8080 Only used to build the default OIDC_REDIRECT_URI

Backups — see Backups & upgrades.

Variable Default Purpose
BACKUP_SCHEDULE_ENABLED (unset) Set to 1 to enable periodic on-disk backups. Off by default
BACKUP_INTERVAL_HOURS 24 Hours between scheduled backups (only when scheduling is enabled)
BACKUP_DIR $DATA_DIR/backups Where scheduled backup archives are written (only when scheduling is enabled)

Local username/password auth works out of the box; OIDC is entirely optional and layered on when those variables are set.

Upgrading

Pull a newer image tag and recreate the container. Schema migrations run automatically on boot and are idempotent. Your /data volume carries everything across the upgrade. See Backups & upgrades.