From f210d533eb318d906eaab7dec879534ae400f30f Mon Sep 17 00:00:00 2001 From: Joakim Persson Date: Mon, 20 Apr 2026 22:12:14 +0200 Subject: [PATCH] Fix root-owned parent dirs left behind by nested volume mounts When a named volume is mounted at a nested path like /home/developer/.local/state/opencode, Docker creates the parent directory (.local/state) as root:root. The existing chown loop only fixed the leaf mount points, leaving parents unwritable by the developer user. Add a non-recursive pre-pass that fixes ownership of the common parent dirs (.local, .local/share, .local/state, .config) so that anything creating new subdirs beneath them works correctly after a fresh container recreate. Regression introduced by commit 967ce7d (devbox-state volume) and only partially addressed by a06dc5f. --- entrypoint.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/entrypoint.sh b/entrypoint.sh index 7628926..f0ecc6d 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -51,6 +51,22 @@ fi # developer user can write to them. FINAL_UID="${TARGET_UID:-$CURRENT_UID}" FINAL_GID="${TARGET_GID:-$CURRENT_GID}" + +# First, fix parent dirs that Docker auto-creates as root:root when it +# materializes nested mount points (e.g. mounting a volume at +# .local/state/opencode creates .local/state as root). Non-recursive — +# we only need the dir node itself; children are handled below or were +# created by the user. +for parent in \ + /home/"$USER_NAME"/.local \ + /home/"$USER_NAME"/.local/share \ + /home/"$USER_NAME"/.local/state \ + /home/"$USER_NAME"/.config; do + if [ -d "$parent" ] && [ "$(stat -c '%u' "$parent" 2>/dev/null)" != "$FINAL_UID" ]; then + chown "$FINAL_UID":"$FINAL_GID" "$parent" 2>/dev/null || true + fi +done + for dir in \ /home/"$USER_NAME"/.local/share/opencode \ /home/"$USER_NAME"/.local/state/opencode \