Bot releases install themselves: signed bundle upload to dumpd, no Docker socket in CI

dumpd gains POST /deploy-bot on the bridge-only auth port: HMAC-SHA256 over the body with BOT_DEPLOY_SECRET,
a 300 MB cap, one install at a time, and the installer's output returned in the response so the CI job shows
it. BOT_DEPLOY_AUTO=0 makes the server refuse. configure.py generates the secret, writes both settings into
/etc/vanguard/deploy.env, installs deployBotBundle.sh as /usr/local/bin/vanguard-deploy-bot and creates
/srv/bot/app; --show prints what to paste into Gitea.

Chose this over mounting the Docker socket into job containers, which would give every CI job root on the
host. Also moved threading/subprocess to dumpd's module imports, which the new module-level lock needs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-11-02 21:32:34 -06:00
parent 22dcf893d5
commit b05f129bed
8 changed files with 111 additions and 24 deletions

View File

@@ -5,9 +5,12 @@ Start with **AGENT.md** in this folder: the stack, the rules, the layout, the we
## How code reaches the server
Your repo's Gitea Actions workflow builds a **release bundle**: one tar.gz holding `main.py`, `app/`,
`website/`, `version.json`, `BUILD.json` and `vendor/` (your dependencies as prebuilt wheels). The admin
installs it with `./deployBotBundle.sh <bundle.tar.gz>` from the stack root; it lands in `/srv/bot/app`,
which is bind-mounted into the container at `/app`, and the previous release is kept for `--rollback`.
`website/`, `version.json`, `BUILD.json` and `vendor/` (your dependencies as prebuilt wheels). **A push to
`main` installs itself**: the workflow's last job posts the bundle to the server's deploy service, which
checks its signature and every checksum, swaps it into `/srv/bot/app` (bind-mounted at `/app`, previous
release kept for `--rollback`) and restarts the container. The install log comes back in the CI job.
A branch or pull request runs the tests and builds the artifact, and deploys nothing.
The image contains **no** bot dependencies: the container imports yours from `/app/vendor`
(`PYTHONPATH=/app/vendor`). Adding a dependency means editing `app/requirements.txt` and pushing — no image
@@ -15,7 +18,7 @@ rebuild, no package index on the server. The image only changes if you need a ne
curl are already there); ask the admin for that.
## Day to day (on the server, in ~/vanguard-stream)
./deployBotBundle.sh vanguard-bot-bundle.tar.gz # install a release
./deployBotBundle.sh vanguard-bot-bundle.zip # install a release by hand (zip or tar.gz)
./deployBotBundle.sh --status # what is installed; container state
./deployBotBundle.sh --rollback # previous release
docker compose logs -f discord-bot # live log