# 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: ```bash 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. **Speed** — `chown -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). ```bash 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.