Fix container image upgrade migrations before gateway readiness (#101881)

* run all 'openclaw upgrade' migrations with container image upgrades

Signed-off-by: sallyom <somalley@redhat.com>

* fix: block gateway startup on plugin repair warnings

Signed-off-by: sallyom <somalley@redhat.com>

---------

Signed-off-by: sallyom <somalley@redhat.com>
This commit is contained in:
Sally O'Malley 2026-07-08 14:19:05 -04:00 committed by GitHub
parent aa27ae9d9f
commit b81666ca6a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1003 additions and 116 deletions

View file

@ -168,6 +168,13 @@ openclaw doctor --lint --all --skip core/doctor/session-locks
`openclaw doctor --post-upgrade` runs plugin compatibility probes for chaining after a build or upgrade. Findings go to stdout; exit code is 1 if any finding has `level: "error"`. Add `--json` for a machine-readable envelope (`{ probesRun, findings }`), suitable for CI, the community `fork-upgrade` skill, and other post-upgrade smoke tooling. If the installed plugin index is missing or malformed, JSON mode still emits the envelope with a `plugin.index_unavailable` error finding.
Container image startup is the exception to the usual "run doctor after
updating" flow. When `openclaw gateway run` starts on a new OpenClaw version, it
runs safe state and plugin repairs before reporting ready. If repair cannot
finish safely, startup exits and tells you to run the same image once with
`openclaw doctor --fix` against the same mounted state/config before restarting
the container normally.
## Notes
- In Nix mode (`OPENCLAW_NIX_MODE=1`), read-only doctor checks still work, but `doctor --fix`, `doctor --repair`, `doctor --yes`, and `doctor --generate-gateway-token` are disabled because `openclaw.json` is immutable. Edit the Nix source for this install instead; for nix-openclaw, use the agent-first [Quick Start](https://github.com/openclaw/nix-openclaw#quick-start).

View file

@ -4200,6 +4200,7 @@ Do not edit it by hand; run `pnpm docs:map:gen`.
- H2: Prerequisites
- H2: Containerized gateway
- H3: Manual flow
- H3: Upgrading container images
- H3: Environment variables
- H3: Observability
- H3: Health checks
@ -4468,6 +4469,7 @@ Do not edit it by hand; run `pnpm docs:map:gen`.
- H2: Podman and Tailscale
- H2: Systemd (Quadlet, optional)
- H2: Config, env, and storage
- H2: Upgrading images
- H2: Useful commands
- H2: Troubleshooting
- H2: Related

View file

@ -412,7 +412,9 @@ That stages grounded durable candidates into the short-term dreaming store while
<Accordion title="7b. Plugin install cleanup">
Doctor removes legacy OpenClaw-generated plugin dependency staging state in `openclaw doctor --fix` / `openclaw doctor --repair` mode: stale generated dependency roots, old install-stage directories, package-local debris from earlier bundled-plugin dependency repair code, and orphaned or recovered managed npm copies of bundled `@openclaw/*` plugins that can shadow the current bundled manifest. Doctor also relinks the host `openclaw` package into managed npm plugins that declare `peerDependencies.openclaw`, so package-local runtime imports such as `openclaw/plugin-sdk/*` keep resolving after updates or npm repairs.
Doctor can also reinstall missing downloadable plugins when config references them but the local plugin registry cannot find them (material `plugins.entries`, configured channel/provider/search settings, configured agent runtimes). During package updates, doctor avoids running package-manager plugin repair while the core package is being swapped; run `openclaw doctor --fix` again after the update if a configured plugin still needs recovery. Gateway startup and config reload do not run package managers; plugin installs remain explicit doctor/install/update work.
Doctor can also reinstall missing downloadable plugins when config references them but the local plugin registry cannot find them (material `plugins.entries`, configured channel/provider/search settings, configured agent runtimes). During package updates, doctor avoids reinstalling plugin packages while the core package is being swapped; run `openclaw doctor --fix` again after the update if a configured plugin still needs recovery. Outside the container image startup exception below, gateway startup and config reload do not run package repair; plugin installs remain explicit doctor/install/update work.
Containerized gateway startup has a narrow upgrade exception: when `openclaw gateway run` starts on a new OpenClaw version, it runs safe state migrations and the existing post-core plugin convergence before readiness, then records a per-version checkpoint. This startup pass can clean stale bundled-plugin records, repair local plugin links, reinstall configured plugin packages when the convergence path requires it, and check active plugin payloads. If startup cannot repair safely, run the same image once with `openclaw doctor --fix` against the same mounted state/config before restarting the container normally.
</Accordion>
<Accordion title="8. Gateway service migrations and cleanup hints">

View file

@ -115,6 +115,28 @@ docker compose up -d openclaw-gateway
Run `docker compose` from the repo root. If you enabled `OPENCLAW_EXTRA_MOUNTS` or `OPENCLAW_HOME_VOLUME`, the setup script writes `docker-compose.extra.yml`; include it after any `docker-compose.override.yml` you maintain yourself, e.g. `-f docker-compose.yml -f docker-compose.override.yml -f docker-compose.extra.yml`.
</Note>
### Upgrading container images
When you replace the OpenClaw image but keep the same mounted state/config, the
new gateway runs startup-safe upgrade migrations and plugin convergence before
readiness. Routine image upgrades should not require a separate
`openclaw doctor --fix` pass.
If startup cannot complete those repairs safely, the gateway exits instead of
reporting healthy. With a restart policy, Docker, Podman, or Kubernetes may show
the gateway container restarting. Keep the mounted state volume, then run the
same image once with `openclaw doctor --fix` as the container command, using the
same state/config mounts the gateway uses:
```bash
docker run --rm -v <openclaw-state>:/home/node/.openclaw <image> openclaw doctor --fix
podman run --rm -v <openclaw-state>:/home/node/.openclaw <image> openclaw doctor --fix
```
After doctor finishes, restart the gateway container with its default command.
In Kubernetes, run the same command in a one-off Job or debug pod mounted to the
same PVC, then restart the Deployment or StatefulSet.
### Environment variables
Optional variables accepted by `scripts/docker/setup.sh` (and, for the gateway container, by `docker-compose.yml` directly):

View file

@ -153,6 +153,35 @@ Useful env vars for the manual launcher (persist these in `~/.openclaw/.env`; th
If you use a non-default `OPENCLAW_CONFIG_DIR` or `OPENCLAW_WORKSPACE_DIR`, set the same variables for both `./scripts/podman/setup.sh` and later `./scripts/run-openclaw-podman.sh launch` commands -- the repo-local launcher does not persist custom path overrides across shells.
## Upgrading images
After you rebuild or pull a new image, restart the container or Quadlet service.
On first startup for a new OpenClaw version, the gateway runs safe state and
plugin repairs before reporting ready.
If the gateway exits instead of becoming ready, run the same image once with
`openclaw doctor --fix` against the same mounted state/config, then restart the
gateway normally:
```bash
OPENCLAW_CONFIG_DIR="${OPENCLAW_CONFIG_DIR:-$HOME/.openclaw}"
OPENCLAW_WORKSPACE_DIR="${OPENCLAW_WORKSPACE_DIR:-$OPENCLAW_CONFIG_DIR/workspace}"
OPENCLAW_PODMAN_IMAGE="${OPENCLAW_PODMAN_IMAGE:-${OPENCLAW_IMAGE:-openclaw:local}}"
podman run --rm -it \
--userns=keep-id \
--user "$(id -u):$(id -g)" \
-e HOME=/home/node \
-e NPM_CONFIG_CACHE=/home/node/.openclaw/.npm \
-v "$OPENCLAW_CONFIG_DIR:/home/node/.openclaw:rw" \
-v "$OPENCLAW_WORKSPACE_DIR:/home/node/.openclaw/workspace:rw" \
"$OPENCLAW_PODMAN_IMAGE" \
openclaw doctor --fix
```
On SELinux hosts, add `,Z` to both bind mounts if Podman blocks access to the
mounted state.
## Useful commands
- **Container logs:** `podman logs -f openclaw`
@ -165,6 +194,7 @@ If you use a non-default `OPENCLAW_CONFIG_DIR` or `OPENCLAW_WORKSPACE_DIR`, set
- **Permission denied (EACCES) on config or workspace:** The container runs with `--userns=keep-id` and `--user <your uid>:<your gid>` by default. Ensure the host config/workspace paths are owned by your current user.
- **Gateway start blocked (missing `gateway.mode=local`):** Ensure `~/.openclaw/openclaw.json` exists and sets `gateway.mode="local"`. `scripts/podman/setup.sh` creates this if missing.
- **Container restarts after an image update:** Run the one-off `openclaw doctor --fix` command in [Upgrading images](#upgrading-images), then start the gateway again.
- **Container CLI commands hit the wrong target:** Use `openclaw --container <name> ...` explicitly, or export `OPENCLAW_CONTAINER=<name>` in your shell.
- **`openclaw update` fails with `--container`:** Expected. Rebuild/pull the image, then restart the container or the Quadlet service.
- **Quadlet service does not start:** Run `systemctl --user daemon-reload`, then `systemctl --user start openclaw.service`. On headless systems you may also need `sudo loginctl enable-linger "$(whoami)"`.

View file

@ -8,6 +8,11 @@ title: "Updating"
Keep OpenClaw up to date.
For Docker, Podman, and Kubernetes image replacements, see
[Upgrading container images](/install/docker#upgrading-container-images). The
gateway runs startup-safe upgrade work before readiness and exits if mounted
state needs manual repair.
## Recommended: `openclaw update`
Detects your install type (npm or git), fetches the latest version, runs `openclaw doctor`, and restarts the gateway.