Containers: Dockerfile must pre-create /state and config dirs with claude ownership #29
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks#29
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
User story
As an operator bringing up a fresh agent container, I want the
Dockerfile to ship mount points (
/state,/home/claude/.config,/home/claude/.config/claude-code) that are already owned by thenon-root
claudeuser, sodocker run -v <named-volume>:/state …produces a writable volume on first mount and the credentials bind
target's parent is traversable.
Follow-up to #27. When piloting container mode on
reviewer, the veryfirst
git cloneinside the container failed with:Root cause: Docker creates named volumes with
root:root 0755unlessthe image's declared mount point already has different ownership.
/statewasn't declared in the image at all, so the volume came upowned by root and unwritable by
uid 1000(theclaudeuser). Thecredentials bind target
/home/claude/.config/claude-code/had thesame problem — Docker auto-created the intermediate directories owned
by root.
Fixed locally to keep the pilot moving; this issue lands the same
change on
mainso future image builds carry it.Acceptance criteria
Dockerfile
USER claude, pre-create/state,/home/claude/.config, and/home/claude/.config/claude-codeowned by
claude:claudewith mode 0755.install -d -o claude -g claude -m 0755 …is the clean one-liner (four invocations inone
RUN, one per path).hundred bytes).
Tests
.forgejo/workflows/qa.yml(the daemonlessdockerfilejob)gains a static check:
grepfor theinstall -d -o claudeblock. Fails the build if missing or regressed.
matching runtime assertion belongs in #26.
Docs
RUNexplainingwhy (volume/bind ownership on first mount).
Out of scope
justfileorsrc/container.ts— both already agreeon the correct paths (fixed in #27).
publish time (tracked in #26).
References
pilot possible at all)
Dependencies
docker buildxthat a release or new operatorpulls — without this the image still ships broken volume ownership
main