Pull the server image on the Pi instead of building it
The Pi now runs registry.mc02.dev/schulcloud-mcp. Its compose file `!reset`s the build section docker-compose.yml declares, so no `docker compose` command there can fall back to building (Compose 2.24 or later). SCHULCLOUD_MCP_TAG pins a commit's image; unset, the Pi follows `latest`. `npm run publish-image` publishes from a development machine. It builds only a clean working tree, so a commit tag names exactly that commit's code, for amd64 and arm64, tagged `latest` and with the short commit id. On an x86 machine arm64 builds under QEMU, which the script checks for and explains rather than registering unasked. PI.md logs in to the registry, pulls and starts instead of building, and updates by publishing and pulling. Rehearsed in a scratch compose project: the image came from the registry, `up -d --build` built nothing, and the server came up healthy with its database and no published ports. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,12 +38,14 @@ this server's bearer check.
|
||||
|
||||
## First deploy
|
||||
|
||||
[PI.md](PI.md) steps 2–5: clone to `/opt/schulcloud-mcp`, write `.env` (the Pi's
|
||||
[PI.md](PI.md) steps 1–5: log in to `registry.mc02.dev`, clone to
|
||||
`/opt/schulcloud-mcp` for the compose files, write `.env` (the Pi's
|
||||
`COMPOSE_FILE`, `CADDY_NETWORK` and `POSTGRES_PASSWORD`, generated secrets, the
|
||||
first Schulcloud token), then:
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
docker compose logs -f schulcloud-mcp
|
||||
```
|
||||
|
||||
@@ -216,15 +218,44 @@ use stdio:
|
||||
|
||||
`MCP_AUTH_TOKEN` is irrelevant in stdio mode — there is no network listener.
|
||||
|
||||
## Publishing an image
|
||||
|
||||
The Pi never builds: `deploy/docker-compose.pi.yml` runs
|
||||
`registry.mc02.dev/schulcloud-mcp` and removes the build section it would
|
||||
otherwise inherit. Images are published from a development machine:
|
||||
|
||||
```bash
|
||||
npm run publish-image
|
||||
docker buildx imagetools inspect registry.mc02.dev/schulcloud-mcp:latest # lists linux/amd64 and linux/arm64
|
||||
```
|
||||
|
||||
`scripts/publish-image.sh` refuses a working tree with uncommitted changes, so
|
||||
a tag always names exactly the code of one commit. It builds for `linux/amd64`
|
||||
and `linux/arm64` and pushes two tags: `latest`, and the short commit id. It
|
||||
also labels the image with the full commit and the repository.
|
||||
|
||||
Two things the build machine needs:
|
||||
|
||||
- **arm64 emulation on an x86 machine.** The script checks for it and prints
|
||||
the command that registers QEMU —
|
||||
`docker run --privileged --rm tonistiigi/binfmt --install arm64` — which lasts
|
||||
until the next reboot.
|
||||
- **A multi-platform push.** Docker's containerd image store supports it
|
||||
directly. Without that store, create a builder first with
|
||||
`docker buildx create --use`.
|
||||
|
||||
## Updating
|
||||
|
||||
```bash
|
||||
cd /opt/schulcloud-mcp && git pull
|
||||
docker compose up -d --build
|
||||
docker compose exec schulcloud-mcp node -e "1" # sanity
|
||||
npm run probe # re-verify the API assumptions
|
||||
npm run publish-image # on a development machine
|
||||
cd /opt/schulcloud-mcp && git pull # on the Pi: compose files and docs
|
||||
docker compose pull && docker compose up -d
|
||||
npm run probe # on a development machine: re-verify the API assumptions
|
||||
```
|
||||
|
||||
A `.env` that pins `SCHULCLOUD_MCP_TAG` needs the new commit id before the pull.
|
||||
Setting the previous one rolls back.
|
||||
|
||||
## Operational notes
|
||||
|
||||
- **Restart policy** is `unless-stopped`; the container comes back after a
|
||||
|
||||
Reference in New Issue
Block a user