agentbbs/docs/deploy.md
Anthony Ettinger 3230807421 Autonomous deploy + free-pod/Premium-email membership
Deploy automation (idempotent, runs on every deploy):
- .github/workflows/deploy.yml: push to main/master (or dispatch) SSHes to the
  droplet and re-runs setup.sh; deploys the pushed branch; smoke-tests :22.
- scripts/self-update.sh + agentbbs-update.timer: autonomous backstop that
  redeploys only when origin advances.
- setup.sh hardened: flock, fetch+reset (survives force-push), fixed the
  always-skipped arcade asset fetch path.

Membership model:
- Free, email-verified members get their own Docker pod (pod@ paywall removed)
  and a /~name homepage (seeded at join@).
- join@ is now interactive: email -> emailed 6-digit code -> enter code.
- Premium ($10 one-time, lifetime via CoinPay) grants a personal
  <name>@host email (new internal/forwardemail; forwardemail.net aliases) and
  custom domains (domain@ gated to Premium).
- ensurePremium() silently verifies/grants/provisions on hub login, join@, and
  domain@. New-signup details emailed to AGENTBBS_SIGNUP_NOTIFY (subject "bbs").

Store: User.Premium + premium/premium_ref cols, ConfirmEmailCode, GrantPremium.
Tests: store_premium_test.go, forwardemail_test.go. Build/vet/gofmt/test green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 07:58:51 +00:00

2.9 KiB

Autonomous deploy

AgentBBS deploys to a single Ubuntu droplet (bbs.profullstack.com). The whole provisioner — setup.sh — is idempotent: it pulls the tracked branch, rebuilds the Go binaries, rewrites the systemd unit / Caddyfile / env, and restarts the service that answers ssh join@bbs.profullstack.com. Re-running it is always safe, so "deploy" just means "run setup.sh again."

Two mechanisms keep the box current, and they cooperate (both go through the same flock in setup.sh, so they never race):

1. Push-triggered — GitHub Actions (.github/workflows/deploy.yml)

On every push to main (and via Run workflow), CI SSHes to the droplet's admin port and runs setup.sh. This is the "runs on every deploy" path.

Configure these repo secrets — Settings → Secrets and variables → Actions:

Secret Required Default Notes
DEPLOY_SSH_KEY yes private key; its public half is in the droplet admin user's ~/.ssh/authorized_keys
DEPLOY_HOST yes bbs.profullstack.com or the droplet IP
DEPLOY_USER no root admin SSH user (needs passwordless sudo if not root)
DEPLOY_PORT no 2202 admin OpenSSH port (setup.sh moves it off :22)

The job bootstraps a bare box (clones /opt/agentbbs if missing), hard-resets to origin/main so it always runs the latest setup.sh, then execs it, and finally smoke-tests that something serves SSH on :22.

2. Pull-triggered — self-update timer (autonomous backstop)

setup.sh also installs agentbbs-update.timer, which runs scripts/self-update.sh every SELF_UPDATE_INTERVAL (default 15 min). That script git fetches origin and, only if the branch advanced or the service is down, re-runs setup.sh. When nothing changed it costs one fetch and exits, so the box self-heals and stays current even if CI is unavailable.

Disable it with SELF_UPDATE=0 ./setup.sh; change the cadence with SELF_UPDATE_INTERVAL=5min ./setup.sh.

First-time bootstrap

The droplet is already provisioned. To bring up a fresh box manually:

git clone https://github.com/profullstack/agentbbs /opt/agentbbs
sudo /opt/agentbbs/setup.sh          # DOMAIN/ADMIN_SSH_PORT/etc. overridable via env

After that, pushes to main deploy automatically.

Operations

journalctl -u agentbbs -f                       # live BBS logs
systemctl status agentbbs                        # service health
systemctl list-timers agentbbs-update.timer      # next self-update
sudo /opt/agentbbs/scripts/self-update.sh --force  # force a redeploy now

Note on the logicsrc connector

@logicsrc/plugin-agentbbs (in the logicsrc monorepo) is a registry connector that talks to this running server over SSH — it is not installed on the droplet and is not needed for ssh join@bbs.profullstack.com to work. The Go server provisioned here is what serves all SSH routes.