mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-04 22:49:41 +02:00
feat(docker): restore in-app self-update in the Compose deployment
Codeman running under docker/docker-compose.yaml lost the ability to update
itself from App Settings -> Updates. The image had no .git (excluded by
.dockerignore), so the install reported as "unknown"; there was no init system
for detectSupervisor() to find; the runtime stage had neither devDependencies
nor a build toolchain; and a pull into the baked /opt/codeman would have landed
in the container's writable layer and been discarded by the next `up`.
Restore it through configuration rather than a second updater, so the release
channel, auto-stash, status file and boot reconcile are all reused unchanged:
- The checkout Compose builds from is bind-mounted over /opt/codeman, so the
update's git checkout and rebuild land on the host and survive recreation.
- The restart is the server exiting; `restart: unless-stopped` relaunches the
container on the new dist/. This is the one supervisor whose updater does NOT
outlive the restart, which is safe only because the terminal "restarting"
marker is written first.
- node_modules and dist are named volumes over the bind mount, so
container-compiled native modules never enter the host checkout.
- The runtime image keeps devDependencies and gains python3/make/g++, since
`npm run build` is tsc + esbuild and node-pty has no Linux prebuild.
An in-place container update applies code only, because a restart reuses the
existing image and config. evaluateEnvironmentGate() reads the target release's
own files with `git show <tag>:<path>` and refuses when server.Dockerfile or
docker-compose.yaml changed, when .env.example gained keys the user's .env
lacks, or when the restart policy would not bring the container back. The
missing-key check matters most: Compose resolves an unset ${VAR} to the empty
string and starts anyway, so a new required setting would otherwise arrive as a
silently blank variable. Every unknown fails open, and the gate is re-evaluated
server-side on POST /api/system/update.
The four global agent CLIs are pinned, because an unpinned CLI bump is the one
environment change no diff-derived gate can see; pinning turns it into a
Dockerfile change the gate already detects.
Adds test/docker-compose-env-parity.test.ts as the merge-side guard (every
compose ${VAR} has an .env.example entry and the reverse) and
test/docker-self-update.test.ts for the pure gate decisions.
Documented in docs/docker-self-update.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013yAQ2y9t81jzSfpStUxx5T
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
---
|
||||
'aicodeman': minor
|
||||
---
|
||||
|
||||
Restore in-app self-update for the Docker Compose deployment.
|
||||
|
||||
App Settings → Updates now works in the container, using the same updater,
|
||||
status file and progress UI as a bare-host install. The Compose file mounts the
|
||||
checkout it builds from at `/opt/codeman`, so an update's `git checkout` and
|
||||
rebuild land on the host and survive container recreation, and the restart is
|
||||
the server exiting — `restart: unless-stopped` relaunches it on the new build.
|
||||
|
||||
An in-place container update applies application code only, since a restarted
|
||||
container reuses its existing image and configuration. The updater therefore
|
||||
refuses a release that changes `docker/server.Dockerfile` or
|
||||
`docker/docker-compose.yaml`, or that adds keys to `docker/.env.example` the
|
||||
user's `.env` has no value for, naming what changed and pointing at
|
||||
`docker/Start-Codeman.sh` on the host. It also refuses when the container's
|
||||
restart policy would not bring it back. The missing-key check matters most:
|
||||
Compose resolves an unset `${VAR}` to the empty string and starts anyway, so a
|
||||
new required setting would otherwise arrive as a silently blank variable.
|
||||
|
||||
Supporting changes:
|
||||
|
||||
- The runtime image keeps devDependencies and gains `python3`/`make`/`g++`, so
|
||||
`npm install` and `npm run build` can run inside the container. This makes the
|
||||
image larger; that is the cost of updating in place.
|
||||
- Build artefacts live in `codeman-node-modules` and `codeman-dist` named
|
||||
volumes so container-compiled native modules never land in the host checkout.
|
||||
- The four global agent CLIs are pinned, so a release needing newer CLI
|
||||
behaviour becomes a Dockerfile change the environment gate can detect.
|
||||
- `docker/Start-Codeman.sh` records the Dockerfile and compose fingerprints the
|
||||
container was created from, which is the baseline the gate compares against.
|
||||
- New CI guard: `test/docker-compose-env-parity.test.ts` fails when a compose
|
||||
variable has no `.env.example` entry, or the reverse.
|
||||
|
||||
Documented in `docs/docker-self-update.md`.
|
||||
Reference in New Issue
Block a user