Problem
Every openclaw agent deploy currently takes 60–90 seconds because each fresh container goes through:
- Incus container creation (~5s)
apt update + dep install (Node, npm, ca-certs, etc.) (~30–40s)
- Download openclaw
rolling tarball from GitHub Releases (~5s)
npm install against the tarball (~20–30s)
- systemd unit setup + first boot (~5s)
Steps 2–4 are identical across every deploy on a given arch and only change when openclaw or its deps change. They're trivially cacheable.
Proposal
Pre-bake a base LXC image with openclaw and all dependencies already installed, published to GitHub Releases, pulled once per host and reused for every subsequent deploy. Mirrors the pattern the openclaw fork CI already uses for the rolling tarball.
Build pipeline
New workflow on jaylfc/tinyagentos (or piggyback on jaylfc/openclaw's existing CI): .github/workflows/build-agent-images.yml.
Matrix: ubuntu-latest (x64) + ubuntu-24.04-arm (arm64).
Per job:
```bash
Spin a clean Debian 13 incus container
incus launch images:debian/13 build-base
Install everything an openclaw agent will ever need at deploy time
incus exec build-base -- bash -c '
apt-get update -qq
apt-get install -y -qq curl ca-certificates nodejs npm python3 ...
mkdir -p /opt/openclaw
curl -fsSL https://github.com/jaylfc/openclaw/releases/latest/download/openclaw-taos-fork-linux-${ARCH}.tgz
| tar -xz -C /opt/openclaw
cd /opt/openclaw && npm install --omit=dev --ignore-scripts
'
incus stop build-base
incus publish build-base --alias taos-openclaw-base
incus image export taos-openclaw-base ./taos-openclaw-base-linux-${ARCH}.tar.gz
```
Tarballs uploaded as Release assets under a rolling-images tag (overwritten each build).
Deployer wiring
`tinyagentos/deployer.py`:
- On first deploy after taOS install (or as part of `taos setup`), check `incus image list` for `taos-openclaw-base`.
- If absent, `curl ... | incus image import - --alias taos-openclaw-base`. One-time cost, ~30–60s depending on bandwidth, ~300–500 MB compressed.
- `incus launch taos-openclaw-base taos-agent- ...` instead of `incus launch images:debian/13 ...`. Container is ready in ~5–10s because openclaw + npm modules + deps are already baked in.
- `install.sh` becomes a thin variant: just write `openclaw.json` + `env` file + start the systemd unit. No more per-deploy network round trips.
Rebuild cadence
- Push to `taos-fork` on `jaylfc/openclaw` (auto via repository dispatch or workflow_run trigger)
- Weekly cron for upstream Debian/security updates
- Manual `workflow_dispatch`
Rolling tag means GitHub Free's 2 GB-per-repo Release limit isn't a concern (we only ever keep two tarballs — one per arch).
Hosting cost reality
- One image ≈ 300–500 MB compressed × 2 archs = ~1 GB max
- GitHub Free: 2 GB/repo Releases storage, unlimited bandwidth on public repos
- Actions runtime: image build ~5–10 min × 2 archs × ~weekly = trivial vs. 2000 min/month free tier on public repos
When/if we outgrow GitHub: swap to Cloudflare R2 (10 GB free) or self-host on the Fasthosts VPS. Out of scope for v1.
Acceptance criteria
Out of scope
- Replacing GitHub Releases with a custom hosting layer (R2, VPS, etc.) — separate issue if we hit the 2 GB cap
- Pre-baking models or per-agent customisations (these belong in agent-specific layers, not the shared base)
- Cross-platform builds beyond Linux (Mac/Windows agent runtime is a separate question)
Related
Problem
Every openclaw agent deploy currently takes 60–90 seconds because each fresh container goes through:
apt update+ dep install (Node, npm, ca-certs, etc.) (~30–40s)rollingtarball from GitHub Releases (~5s)npm installagainst the tarball (~20–30s)Steps 2–4 are identical across every deploy on a given arch and only change when openclaw or its deps change. They're trivially cacheable.
Proposal
Pre-bake a base LXC image with openclaw and all dependencies already installed, published to GitHub Releases, pulled once per host and reused for every subsequent deploy. Mirrors the pattern the openclaw fork CI already uses for the
rollingtarball.Build pipeline
New workflow on
jaylfc/tinyagentos(or piggyback onjaylfc/openclaw's existing CI):.github/workflows/build-agent-images.yml.Matrix:
ubuntu-latest(x64) +ubuntu-24.04-arm(arm64).Per job:
```bash
Spin a clean Debian 13 incus container
incus launch images:debian/13 build-base
Install everything an openclaw agent will ever need at deploy time
incus exec build-base -- bash -c '
apt-get update -qq
apt-get install -y -qq curl ca-certificates nodejs npm python3 ...
mkdir -p /opt/openclaw
curl -fsSL https://github.com/jaylfc/openclaw/releases/latest/download/openclaw-taos-fork-linux-${ARCH}.tgz
| tar -xz -C /opt/openclaw
cd /opt/openclaw && npm install --omit=dev --ignore-scripts
'
incus stop build-base
incus publish build-base --alias taos-openclaw-base
incus image export taos-openclaw-base ./taos-openclaw-base-linux-${ARCH}.tar.gz
```
Tarballs uploaded as Release assets under a
rolling-imagestag (overwritten each build).Deployer wiring
`tinyagentos/deployer.py`:
Rebuild cadence
Rolling tag means GitHub Free's 2 GB-per-repo Release limit isn't a concern (we only ever keep two tarballs — one per arch).
Hosting cost reality
When/if we outgrow GitHub: swap to Cloudflare R2 (10 GB free) or self-host on the Fasthosts VPS. Out of scope for v1.
Acceptance criteria
Out of scope
Related