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:
27
README.md
27
README.md
@@ -240,12 +240,27 @@ for the bot, and `discord-bot`, a Python 3.12 container that runs `/app/main.py`
|
||||
installed. Credentials live in `.env` (generated by `configure.py`; bot token + guild ID are asked in `--full`
|
||||
or the `[d]` menu item; `./configure.py --show` prints them).
|
||||
|
||||
**Releases are self-contained bundles, not loose files.** The bot repo's Gitea Actions workflow runs its tests
|
||||
and then builds one tar.gz holding `main.py`, `app/`, `website/`, `BUILD.json` **and `vendor/`** — its own
|
||||
dependencies, as prebuilt wheels for this image's Python. `./deployBotBundle.sh <bundle.tar.gz>` verifies it
|
||||
against `BUILD.json`, swaps it into `/srv/bot/app` (bind-mounted at `/app`, previous release kept beside it)
|
||||
and restarts the container. `PYTHONPATH=/app/vendor` is how the code finds its dependencies, so **a new
|
||||
dependency never needs an image rebuild** and the server never contacts a package index.
|
||||
**Releases are self-contained bundles, and a push to `main` deploys itself.** The bot repo's Gitea Actions
|
||||
workflow runs its tests and then builds one tar.gz holding `main.py`, `app/`, `website/`, `BUILD.json` **and
|
||||
`vendor/`** — its own dependencies, as prebuilt wheels for this image's Python. `PYTHONPATH=/app/vendor` is how
|
||||
the code finds them, so **a new dependency never needs an image rebuild** and the server never contacts a
|
||||
package index.
|
||||
|
||||
The workflow's last job posts that bundle to **dumpd** at `POST /deploy-bot` on 8081 — the Docker-bridge-only
|
||||
port the firewall already restricts, so a CI job never needs the Docker socket or an ssh key. dumpd checks an
|
||||
HMAC-SHA256 signature over the body, then runs `/usr/local/bin/vanguard-deploy-bot` (this repo's
|
||||
`deployBotBundle.sh`), which verifies every file against `BUILD.json`, swaps the bundle into `/srv/bot/app`
|
||||
(bind-mounted at `/app`, previous release kept beside it) and restarts the container. The install log goes back
|
||||
in the HTTP response, so it appears in the CI job.
|
||||
|
||||
Two settings, both generated into `.env` and copied to `/etc/vanguard/deploy.env` by `configure.py`:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| `BOT_DEPLOY_SECRET` | 64 hex chars. Paste it into Gitea → the bot repo → Settings → Actions → Secrets as **`BOT_DEPLOY_SECRET`**. `./configure.py --show` prints it. |
|
||||
| `BOT_DEPLOY_AUTO` | `1` (default) accepts CI installs; `0` makes dumpd refuse them with 403 and you install by hand. |
|
||||
|
||||
By hand, any time:
|
||||
|
||||
./deployBotBundle.sh vanguard-bot-bundle.zip # install a release (the artifact as Gitea hands it over, zip or tar.gz)
|
||||
./deployBotBundle.sh --latest # fetch the newest main build first (needs BOT_REPO_TOKEN in .env)
|
||||
|
||||
Reference in New Issue
Block a user