# 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 fetch`es 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: ```sh 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 ```sh 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.