Files
qwen3-6-lora/data/raw/sanitized/plans/tengo-un-problema-cuando-snazzy-kazoo.md
T

4.8 KiB

Fix slow/failing chown -R in entrypoint.sh on Mac ARM bind mounts

Context

On macOS (Apple Silicon), Docker Desktop bind-mounts host project folders (e.g. /home/aleleba/projects/telus/telus-board-report) into the container over a virtualized filesystem (virtiofs/gRPC-FUSE) that does not support changing file ownership from inside the container. entrypoint.sh:79 runs:

sudo chown -R ${HOME_USER} /home/${HOME_USER}

This recurses into those bind-mounted directories too, including huge node_modules trees, and every single file inside them fails with Operation not permitted. Two real problems come from this, not just one:

  1. Speedchown -R walks every file individually; over tens of thousands of node_modules/.venv entries this is very slow.
  2. Correctness (bigger issue found during investigation) — the script starts with set -eu. chown -R still returns a non-zero exit status once it finishes (even though it keeps going and reports every failure), and this line is not guarded by || true or an if. Confirmed locally: a failing chown under set -e aborts the script immediately at that line. That means once this line fails, everything after it in entrypoint.sh never runs — no .ssh permission fixup, no custom-scripts, no extension install, and critically the final code tunnel ... command that actually starts the VS Code tunnel. So this isn't just "slow," it can silently prevent the container from ever reaching the tunnel start step on a run where a permission error occurs.

The user has confirmed ownership doesn't actually need to change on these mounted folders — the Dockerfile already does chmod -R a+rwX /home at build time (Dockerfile:41), and the host-mounted files are already world-writable (777), so aleleba can read/write them regardless of chown succeeding.

Fix

Edit entrypoint.sh:79, replacing the whole-home recursive chown with a find -xdev based version that:

  • Stays on the container's own filesystem (-xdev) so it never descends into separately-mounted bind volumes like /home/${HOME_USER}/projects/... — this is what fixes the slowness, without hardcoding folder names like node_modules/.venv (it works generically for any bind-mounted subtree, not just those two).
  • Never aborts the script even if an unexpected chown failure occurs elsewhere, by appending || true (this is the correctness fix — restores the guarantee that the rest of entrypoint.sh, including the VS Code tunnel startup, always runs).
sudo find "/home/${HOME_USER}" -xdev -exec chown "${HOME_USER}" {} + 2>/dev/null || true

This is a single-line change to entrypoint.sh; no other recursive chown/chmod calls in the script (lines 72, 132, 137, 142) are touched, since those aren't the ones hitting bind-mounted project directories.

This is not a Mac-only fix. -xdev skips any directory that is a separate mount point (different device id) from /home/${HOME_USER} itself — that's true for bind mounts on Linux/Synology just as much as on macOS. The difference is only in symptom:

  • On macOS (virtiofs/gRPC-FUSE), chown on the bind-mounted files fails outright (Operation not permitted), which — combined with the set -e bug above — can abort the whole entrypoint before the tunnel starts.
  • On Linux, the same chown -R walk into node_modules/.venv succeeds file-by-file (root can chown across a Linux bind mount), so there's no error output, but it still pays the same per-file syscall cost — this is almost certainly why the user's other, working Linux/Synology environment is also slow to start, just silently.

Because the fix skips crossing the mount boundary rather than special-casing specific folder names or the host OS, one change fixes both the correctness bug (Mac) and the startup latency (all environments) with no behavior change for anything that lives on the container's own filesystem (.ssh, dotfiles, .vscode*, etc. are chowned exactly as before).

Verification

  1. Read the diff to confirm only line 79 changed and the semantics (still chowning to HOME_USER, still running as root via sudo) are preserved.
  2. Locally simulate the set -e abort scenario (same repro used during investigation: a chown -R hitting a permission-denied/missing path under set -eu kills the script) and confirm the new find -xdev ... || true line does not abort a set -eu script even when it encounters a permission error.
  3. Rebuild the image (docker build .) to confirm the Dockerfile/entrypoint still builds cleanly.
  4. If possible, run the container with a bind-mounted node_modules-heavy directory (mirroring the user's Mac setup) and confirm: no Operation not permitted spam, the entrypoint completes quickly, and the code tunnel command still launches at the end of the log.