Self-host the hub: Operations

Self-host the hub

Operations

Run a self-hosted hub, including cron, log retention, D1 backups, key rotation, upgrades, and monitoring.

Cron

The Worker has a cron trigger, */5 * * * *, defined in wrangler.toml. Check the scheduled handler in hub/src to see what runs on each tick. If cron stops, confirm the trigger in the Cloudflare dashboard under the Worker’s Triggers tab.

Log retention

Job logs are stored in the R2 bucket bound as LOGS. Log uploads are capped at 10 MiB per job, and log links are signed and valid for 15 minutes. Retention is yours to define. Check the hub source for any built-in cleanup, then add an R2 lifecycle rule in the Cloudflare dashboard (R2, your bucket, Settings, Object lifecycle rules) to expire old logs.

When someone runs /hookci delete-my-data or uninstalls the GitHub App, the hub handles purging as the code defines. Check the repository for the purge schedule before you promise a deadline to users.

Backups

Export the D1 database regularly.

npx wrangler d1 export hookci-hub --remote --output hookci-hub-backup.sql

Store backups encrypted and outside the repository. The export includes encrypted tokens, so protect it like a secret. To restore into a new database, create it with wrangler d1 create and import the file as the Wrangler documentation describes for d1 execute --file.

Back up the R2 bucket separately if you need to keep logs. Keep your secrets in a password manager, because Wrangler cannot read them back.

Key rotation

TOKEN_ENC_KEYS and LOG_SIGNING_KEYS are key rings so you can add a new key without breaking existing data. Check how the hub parses each variable in hub/src for the list format and which position is used for new writes.

  1. Generate a new key.

    openssl rand -base64 32
  2. Add it to the key ring in the format the code expects, keeping the old key in the ring so existing data still decrypts or verifies.

    npx wrangler secret put TOKEN_ENC_KEYS
  3. Wait until old data is no longer needed. For log signing keys, 15 minutes is enough for outstanding links. For token encryption keys, check the repository for whether stored tokens are re-encrypted on use.

  4. Remove the old key from the ring and set the secret again.

STATE_SIGNING_KEY is a single key. Changing it invalidates in-flight OAuth flows only. For the GitHub private key, the webhook secret, and Slack secrets, rotate in the GitHub or Slack app settings and update the matching Worker secret.

Upgrades

  1. Read the release notes on the repository for the version you are moving to.

  2. Pull the new version and install dependencies.

    git pull
    cd hub
    npm ci
  3. Back up D1, then apply migrations.

    npx wrangler d1 export hookci-hub --remote --output pre-upgrade.sql
    npx wrangler d1 migrations apply hookci-hub --remote
  4. Deploy.

    npx wrangler deploy
  5. Regenerate manifests if the release notes say the GitHub or Slack manifest changed, and update the apps to match.

Upgrade agents with sudo hookci upgrade. Use hookci upgrade --check to see whether an update exists (exit code 10 means yes). Keep agents and the hub on compatible versions, as the release notes describe.

Monitoring

Stream live logs from the Worker.

npx wrangler tail

Check these when something looks wrong:

  • Webhook deliveries: the GitHub App’s Advanced tab shows each delivery and response code.
  • Slack: failed commands or buttons usually mean a wrong signing secret or request URL.
  • Agents: journalctl -u hookci-agent@<installation-id> -f on the agent host, and hookci doctor.
  • Cloudflare dashboard: Worker requests, errors, and CPU time, plus D1 and R2 usage.

Slack posts are rate limited to about one per second per channel, which the hub respects, so bursts of runs can post with a delay.