Skip to main content
The self-host/ Compose configuration runs prebuilt images on your server. Obtain compatible images before starting it; recent releases require a matching dashboard build for portable hosting. Images and corresponding source currently require authorized private-beta access.
  1. Check the release manifest before upgrading. Legacy schema 1 releases include four images for AMD64 and ARM64. Schema 2 releases include only API, bot and background worker images for ARM64; the dashboard artifact targets Cloudflare. They are not complete portable Compose bundles. On ARM64, use the three supplied runtime images and build the portable dashboard from the exact same release’s source. On other architectures, build all four images. Use the repository root as the build context and apps/<app>/Dockerfile for api, bot, worker, and dashboard; build for your server’s architecture and publish the resulting images to your registry. The Cloudflare dashboard artifact cannot be used as the Compose dashboard image. Verify publisher signatures for supplied images and pin all four Compose image references to immutable digests, never moving tags.
  2. Copy config.env.example to config.env. Use separate random migration and runtime database passwords and set your public HTTPS origin.
  3. Copy each application’s *.env.sample to its own *.env. Fill your Discord application identity, bot token, OAuth secret and session secret. Restrict populated files to mode 0600; do not create a repository-root .env.
  4. Enable Guild Members and Message Content intents. Register your HTTPS origin followed by /api/auth/callback/discord and /api/internal/install/callback. Install with the bot and application-command scopes.
  5. Authenticate to the private image registry using read-only package access. From self-host/, start the bundle:
Route your HTTPS reverse proxy to 127.0.0.1:3000. Database and backend services stay internal. Telemetry is disabled by default. Retain the PostgreSQL 18 volume mount at /var/lib/postgresql.

Create the first account

Set PUP_SIGNUPS_ENABLED=true in self-host/config.env, then recreate the API container from self-host/:
Sign in through Discord with the first intended account. Immediately set PUP_SIGNUPS_ENABLED=false in config.env and run the same recreation command again. The value in config.env overrides api.env; ensure it is not overridden by an exported PUP_SIGNUPS_ENABLED variable in your shell. A plain Compose restart does not apply changed environment values. Verify the running API has closed signups:
If this check fails, correct the configuration and recreate the API before continuing. Existing accounts can still sign in. Account creation does not grant an installation-operator role. Validate Connection status, Cases, staff access, and your chosen features in a disposable server before enforcement. Configuration password values initialize database roles; editing them does not rotate existing database credentials. Follow backup and recovery before upgrading or changing persistent state.

Optional public progress snapshot

Without extra configuration, the roadmap uses its bundled public catalog. An operator may mount an atomically updated, validated snapshot file and set PUP_ROADMAP_SNAPSHOT_PATH in the API environment. No planning-service account or credential is required by the application. Invalid snapshots are rejected.

Installation operators

Server ownership manages that server’s settings and Pup access. Installation operators can also use advanced runtime diagnostics and private-object restore. These tools require the existing super-admin account role in both managed and self-hosted deployments. Normal Discord permissions and server access checks still apply. After the intended operator signs in, use an authorized source checkout with its existing database environment to preview promotion:
Review the result, then repeat with --apply. To revoke operator access, use --role user through the same preview and apply steps. The command changes the existing signed-in account; it does not create a new account. Keep database credentials private. There is no operator-role management screen.

Shared rate limits

The Compose setup includes Redis on its private service network for anonymous submission, report, and suggestion intake rate limits. It exposes no host port. When running bot processes separately, set REDIS_URL to the same Redis instance in each process. Redis stores expiring counters under hashed keys, not submission text. PostgreSQL retains moderation and delivery records. If Redis is unavailable, anonymous submissions, reports, and suggestions ask the member to retry; other features remain available. Redis counters are temporary and reset on restart. Existing durable submission quotas remain enforced. Do not expose Redis directly to the internet.