Problem
When running Netclaw in Docker with a bind mount for data (e.g., ./data:/home/netclaw/.netclaw), the container crashes immediately on startup with System.UnauthorizedAccessException: Access to the path '/home/netclaw/.netclaw/identity' is denied. followed by a core dump (exit code 134).
Root Cause
The Dockerfile runs the daemon as a dedicated non-root user (netclaw, UID 1654). Docker bind mounts inherit the ownership/permissions of the host directory. If the host ./data is owned by the host user (typically UID 1000), UID 1654 cannot create the required subdirectories. Program.cs calls bootstrapPaths.EnsureDirectoriesExist() before anything else, which throws and crashes the process. The error message is a raw stack trace, providing no actionable guidance to the operator.
Proposed Fixes (Two Axes)
1. Prevention: Entrypoint ownership fix
Run the entrypoint as root, check if /home/netclaw/.netclaw (and optionally /tools) is owned by UID 1654. If not, run chown -R 1654:1654. Then drop privileges to the netclaw user before starting the daemon supervisor loop. This matches the industry standard used by Postgres, Redis, Nextcloud, etc.
- Update
Dockerfile to remove USER netclaw at the bottom.
- Update
entrypoint.sh to perform the chown check, then su -s /bin/bash netclaw into the supervisor loop.
2. Defense-in-Depth: Graceful error reporting
Wrap EnsureDirectoriesExist() to catch UnauthorizedAccessException / IOException per directory. Aggregate all failures and throw a single descriptive exception at the end with:
- A list of failed directories
- The current container user and UID
- Actionable advice (e.g., "This looks like a Docker bind-mount ownership mismatch. The entrypoint should have fixed this automatically...")
- Exit cleanly with code 1 instead of core dumping.
This ensures that if the entrypoint fix is bypassed or fails (e.g., read-only FS), the operator gets a helpful error instead of a cryptic stack trace.
Problem
When running Netclaw in Docker with a bind mount for data (e.g.,
./data:/home/netclaw/.netclaw), the container crashes immediately on startup withSystem.UnauthorizedAccessException: Access to the path '/home/netclaw/.netclaw/identity' is denied.followed by a core dump (exit code 134).Root Cause
The Dockerfile runs the daemon as a dedicated non-root user (
netclaw, UID 1654). Docker bind mounts inherit the ownership/permissions of the host directory. If the host./datais owned by the host user (typically UID 1000), UID 1654 cannot create the required subdirectories.Program.cscallsbootstrapPaths.EnsureDirectoriesExist()before anything else, which throws and crashes the process. The error message is a raw stack trace, providing no actionable guidance to the operator.Proposed Fixes (Two Axes)
1. Prevention: Entrypoint ownership fix
Run the entrypoint as
root, check if/home/netclaw/.netclaw(and optionally/tools) is owned by UID 1654. If not, runchown -R 1654:1654. Then drop privileges to thenetclawuser before starting the daemon supervisor loop. This matches the industry standard used by Postgres, Redis, Nextcloud, etc.Dockerfileto removeUSER netclawat the bottom.entrypoint.shto perform thechowncheck, thensu -s /bin/bash netclawinto the supervisor loop.2. Defense-in-Depth: Graceful error reporting
Wrap
EnsureDirectoriesExist()to catchUnauthorizedAccessException/IOExceptionper directory. Aggregate all failures and throw a single descriptive exception at the end with:This ensures that if the entrypoint fix is bypassed or fails (e.g., read-only FS), the operator gets a helpful error instead of a cryptic stack trace.