mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
fix(docker): keep SIGTERM reaching the server, pin root's PATH, probe writability
Three changes to how the Compose container starts as root and drops to PUID:PGID, each reproduced on Docker 29.1.3 / Compose v5.5.0 with a minimal image of the same shape as server.Dockerfile. - cap_add gains KILL. `init: true` makes tini PID 1, and tini stays root while the entrypoint drops the server to PUID. Signalling a process of a different uid needs CAP_KILL, and `cap_drop: ALL` had removed it, so every `docker compose down`/`restart` ended in `[FATAL tini (1)] Unexpected error when forwarding signal: 'Operation not permitted'` and the server being SIGKILLed instead of running `server.stop()`. Measured: without KILL the trap never fires, with it the child logs `GOT SIGTERM`. - /opt/codeman-cli/bin is appended to PATH, never prepended, and entrypoint.sh pins its own PATH to the system directories before its first command. The prefix is chowned to the runtime account so sessions can update the agent CLIs in place, and the root entrypoint resolved stat/chown/setpriv by bare name through it: a `setpriv` planted there by the unprivileged uid ran as uid 0 at the next start. The image's full PATH is handed back to the server at the exec (`env PATH=...`), since Codeman resolves the CLIs through it. - The ownership gate becomes a writability probe. A directory owned by neither root nor PUID:PGID is no longer refused on ownership alone; it is tested with `setpriv --reuid PUID --regid PGID --groups <same groups> test -w`, the exact identity the server gets, so a group-writable tree, an ACL or a CIFS/NFS mount reporting some unrelated uid all pass, and the refusal names path, owner and PUID:PGID. Root-owned directories are still chowned first. Also: a pre-flight runs the drop before touching anything and, when it fails, prints the cap_add list the compose file needs, so an out-of-tree compose file (Unraid's Compose Manager) gets a one-line diagnosis instead of a restart loop; `--bounding-set -all` is gone, since it is a silent no-op without CAP_SETPCAP; a root:root Docker socket now produces a warning that Docker cases will not work rather than silently losing group 0 at the drop; and CODEMAN_ALLOWED_HOSTS is forwarded from .env with an empty default (documented as a commented entry in .env.example so the parity test and the updater's env gate both stay quiet). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,12 @@ CODEMAN_PASSWORD=changeme
|
||||
# Required. Username for Codeman HTTP Basic authentication.
|
||||
CODEMAN_USERNAME=admin
|
||||
|
||||
# Optional. Extra Host-header allowlist entries for a reverse-proxied domain
|
||||
# (comma-separated; a bare `.suffix` matches every subdomain). Without it a
|
||||
# proxied request is rejected with `403 Forbidden: host not allowed`. See
|
||||
# README.md, "Reverse-proxy host allowlist".
|
||||
# CODEMAN_ALLOWED_HOSTS=codeman.example.com,.internal.example.com
|
||||
|
||||
# Optional: authenticate Gemini CLI without an interactive login.
|
||||
GEMINI_API_KEY=
|
||||
|
||||
|
||||
Reference in New Issue
Block a user