mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
chore(docker): add Update-Codeman.sh for scripted major-update rebuilds
docker/README.md and docs/docker-self-update.md both already point operators at "stop the stack, rebuild, restart" for anything the in-app updater refuses to apply (a changed server.Dockerfile, a changed docker-compose.yaml, or a new required .env key) — but that was a manual, hand-typed procedure with no script of its own, unlike every other start/update path this deployment has. docker/Update-Codeman.sh scripts it: `docker compose down`, then an unconditional `docker compose build --no-cache` (a major update should be certain of what actually ships, not reuse whatever layers happened to be cached), then hands off to the existing Start-Codeman.sh for the same careful PUID/PGID, override-file and fingerprint handling every other start already goes through — rather than reimplementing any of that by hand and risking it drifting out of step. An optional --volumes/-v flag also removes the codeman-node-modules/ codeman-dist named volumes, the scripted form of the "Resetting the build artefacts" procedure docs/docker-self-update.md already documents by hand. Safe: those two are the only named volumes this stack declares; application data and case workspaces are host bind mounts, never touched by `docker compose down` either way. Docs updated: a "Major updates" section in docker/README.md, and a pointer from docs/docker-self-update.md's existing "Resetting the build artefacts" troubleshooting entry. Tests: extended test/docker-entrypoint.test.ts (the existing home for Start-Codeman.sh's own static checks) with a bash -n parse check, the down-before-build-before-handoff ordering, the --volumes flag's effect, unrecognised-argument handling, and byte-for-byte agreement with Start-Codeman.sh's own override-file resolution logic (so `down` here and `up` there can never target different Compose files). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N6eadpRyqpA9PD3i139cSD
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
9466acfc1a
commit
9ba90a674a
@@ -41,6 +41,26 @@ Releases that change `server.Dockerfile`, `docker-compose.yaml`, or add a key to
|
||||
changed, and asks you to run `Start-Codeman.sh` here on the host instead. Details:
|
||||
[`../docs/docker-self-update.md`](../docs/docker-self-update.md).
|
||||
|
||||
### Major updates
|
||||
|
||||
`Start-Codeman.sh` rebuilds the image and clears the build-artefact volumes on
|
||||
its own, but only when it detects the checkout's HEAD or `package-lock.json`
|
||||
moved — exactly right for an ordinary `git pull`, too conservative when a
|
||||
release note (or the updater's own blocker message) calls for starting over.
|
||||
For that case, `docker/Update-Codeman.sh` stops the stack, force-rebuilds the
|
||||
image with no layer cache, then hands off to `Start-Codeman.sh` for the usual
|
||||
start:
|
||||
|
||||
```sh
|
||||
bash docker/Update-Codeman.sh
|
||||
```
|
||||
|
||||
Add `--volumes` to also clear the `codeman-node-modules`/`codeman-dist`
|
||||
volumes — the scripted form of "Resetting the build artefacts" in
|
||||
[`../docs/docker-self-update.md`](../docs/docker-self-update.md). Those two
|
||||
are the only named volumes this stack declares; application data and case
|
||||
workspaces are host bind mounts and are never touched either way.
|
||||
|
||||
## Local customisation
|
||||
|
||||
Compose merges `docker-compose.override.yml` on top of `docker-compose.yaml`. Keep host-specific changes there rather than editing `docker-compose.yaml`, so this repository can be updated without losing them. Both `docker-compose.override.yml` and `docker-compose.override.yaml` are ignored by Git.
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# The scripted major-update path for the Docker Compose deployment.
|
||||
#
|
||||
# docker/README.md and docs/docker-self-update.md both point operators here for
|
||||
# anything the in-app updater itself refuses to apply: a changed
|
||||
# `server.Dockerfile`, a changed `docker-compose.yaml`, or a new required
|
||||
# `.env.example` key. None of those can be applied by a container restarting
|
||||
# itself — a restart reuses the existing image and configuration (see "The
|
||||
# environment gate" in docs/docker-self-update.md) — so this script does the
|
||||
# three things an in-place update cannot: stop the stack, force a real image
|
||||
# rebuild with no layer cache, then hand off to Start-Codeman.sh for the same
|
||||
# careful PUID/PGID, override-file and fingerprint handling every other start
|
||||
# goes through.
|
||||
#
|
||||
# This is the scripted form of "Resetting the build artefacts" in
|
||||
# docs/docker-self-update.md (`docker compose down -v`, then
|
||||
# `Start-Codeman.sh`), plus the unconditional `--no-cache` a major update
|
||||
# warrants: `Start-Codeman.sh` on its own only rebuilds without the cache flag,
|
||||
# and only clears the two build-artefact volumes when it detects the checkout's
|
||||
# HEAD or `package-lock.json` moved — exactly right for an ordinary `git pull`,
|
||||
# too conservative when the ask is "start over, certain of what ships".
|
||||
#
|
||||
# Usage: docker/Update-Codeman.sh [--volumes]
|
||||
# --volumes, -v Also remove the codeman-node-modules/codeman-dist named
|
||||
# volumes, so the fresh image's own node_modules/dist are
|
||||
# what actually run instead of sitting unused behind a
|
||||
# Docker-seeded volume's old content (Docker only seeds a
|
||||
# named volume from the image while that volume is EMPTY).
|
||||
# Safe: those two are the ONLY named volumes this stack
|
||||
# declares (`docker-compose.yaml`) — application data and
|
||||
# case workspaces are host bind mounts, never touched by
|
||||
# `docker compose down`, with or without this flag.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||
env_file="$script_dir/.env"
|
||||
compose_file="$script_dir/docker-compose.yaml"
|
||||
|
||||
remove_volumes=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--volumes | -v)
|
||||
remove_volumes=1
|
||||
;;
|
||||
*)
|
||||
printf 'Error: unrecognised argument: %s\n' "$arg" >&2
|
||||
printf 'Usage: %s [--volumes]\n' "$0" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ! -f "$env_file" ]]; then
|
||||
printf 'Error: Docker environment file is missing: %s\n' "$env_file" >&2
|
||||
printf 'Create it from %s/.env.example before running this script.\n' "$script_dir" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Same override-file discovery as Start-Codeman.sh, and deliberately kept in
|
||||
# step with it: a stack started through one script and updated through the
|
||||
# other must resolve to the exact same Compose files, or `down` here and `up`
|
||||
# there could target different configurations. Compose's own precedence
|
||||
# (measured on v5.5.0 with both present: it uses .yml and ignores .yaml).
|
||||
override_yml="$script_dir/docker-compose.override.yml"
|
||||
override_yaml="$script_dir/docker-compose.override.yaml"
|
||||
if [[ -f "$override_yml" && -f "$override_yaml" ]]; then
|
||||
printf 'Warning: both %s and %s exist; Compose uses .yml and ignores .yaml.\n' \
|
||||
"$override_yml" "$override_yaml" >&2
|
||||
fi
|
||||
compose_files=(-f "$compose_file")
|
||||
for override_file in "$override_yml" "$override_yaml"; do
|
||||
if [[ -f "$override_file" ]]; then
|
||||
compose_files+=(-f "$override_file")
|
||||
printf 'Using Compose override file: %s\n' "$override_file"
|
||||
break
|
||||
fi
|
||||
done
|
||||
compose_command=(docker compose --env-file "$env_file" "${compose_files[@]}")
|
||||
|
||||
printf 'Stopping the stack...\n'
|
||||
if [[ "$remove_volumes" == '1' ]]; then
|
||||
printf 'Also removing the codeman-node-modules/codeman-dist volumes (--volumes).\n'
|
||||
"${compose_command[@]}" down --volumes
|
||||
else
|
||||
"${compose_command[@]}" down
|
||||
fi
|
||||
|
||||
# --no-cache, always: a plain `build` reuses cached layers (npm install, apt
|
||||
# packages, the CLI installs baked into the image) and can silently keep them
|
||||
# frozen at whatever they were the day the cache was populated — exactly wrong
|
||||
# for a major update, whose whole point is being certain of what actually
|
||||
# ships. `scripts/build-agent-image.mjs` makes the same call for the same
|
||||
# reason (see its entry in CLAUDE.md's Additional Commands table).
|
||||
printf 'Building a fresh image (--no-cache)...\n'
|
||||
"${compose_command[@]}" build --no-cache
|
||||
|
||||
# Start-Codeman.sh does everything a plain `up -d` does not: resolves
|
||||
# PUID/PGID from CODEMAN_APPDATA_PATH's owner, pre-creates CODEMAN_CASES_PATH
|
||||
# with the right ownership, resolves DOCKER_SOCKET_GID, records the
|
||||
# server.Dockerfile/docker-compose.yaml fingerprint the in-app updater's gate
|
||||
# reads on every future update, and clears the build-artefact volumes itself
|
||||
# if it finds the checkout's source moved since the last start. Reimplementing
|
||||
# any of that here would only risk drifting out of step with it — hand off
|
||||
# instead, exactly as docs/docker-self-update.md's own reset procedure does.
|
||||
printf 'Handing off to Start-Codeman.sh...\n'
|
||||
exec "$script_dir/Start-Codeman.sh"
|
||||
Reference in New Issue
Block a user