Problem
gh-aw assumes the runner service account home is /home/runner and that Copilot CLI state lives at /home/runner/.copilot. On self-hosted runners where the service account has a different home (e.g., /home/actions, /var/lib/runner), the agent either fails to find config or attempts to chroot/bind-mount paths that don't exist.
The current workaround requires users to create a compatibility shim that manufactures /home/runner/.copilot and symlinks back to the real runner account — adding fragile infrastructure complexity.
Context
Reported in github/gh-aw#27260.
Root Cause
Several places hardcode /home/runner:
containers/agent/entrypoint.sh — home directory used for chroot bind mounts and UID/GID remapping
src/docker-manager.ts — generateDockerCompose() likely hard-codes whitelisted $HOME subdirs (.copilot, .cache, etc.) under /home/runner
- Ownership reset logic assumes
runner:runner as the target user
Proposed Solution
- In
src/docker-manager.ts: Replace the hardcoded /home/runner with a runtime-derived value. Read HOME env var (or os.homedir()) at AWF startup and pass it into the Docker Compose config as an env var (e.g., AWF_RUNNER_HOME).
- In
containers/agent/entrypoint.sh: Replace hardcoded /home/runner references with \$\{AWF_RUNNER_HOME:-/home/runner} so the fallback preserves existing behavior.
- In
src/cli.ts: Add a --runner-home <path> CLI flag as an optional override for cases where auto-detection isn't sufficient.
- Update bind mount list in
src/docker-manager.ts: Construct the whitelisted $HOME subdirs dynamically using the resolved runner home path.
- Add a test in
src/docker-manager.test.ts verifying that a non-default HOME value propagates correctly through the generated Docker Compose config.
Generated by Firewall Issue Dispatcher · ● 436.3K · ◷
Problem
gh-awassumes the runner service account home is/home/runnerand that Copilot CLI state lives at/home/runner/.copilot. On self-hosted runners where the service account has a different home (e.g.,/home/actions,/var/lib/runner), the agent either fails to find config or attempts to chroot/bind-mount paths that don't exist.The current workaround requires users to create a compatibility shim that manufactures
/home/runner/.copilotand symlinks back to the real runner account — adding fragile infrastructure complexity.Context
Reported in github/gh-aw#27260.
Root Cause
Several places hardcode
/home/runner:containers/agent/entrypoint.sh— home directory used for chroot bind mounts and UID/GID remappingsrc/docker-manager.ts—generateDockerCompose()likely hard-codes whitelisted$HOMEsubdirs (.copilot,.cache, etc.) under/home/runnerrunner:runneras the target userProposed Solution
src/docker-manager.ts: Replace the hardcoded/home/runnerwith a runtime-derived value. ReadHOMEenv var (oros.homedir()) at AWF startup and pass it into the Docker Compose config as an env var (e.g.,AWF_RUNNER_HOME).containers/agent/entrypoint.sh: Replace hardcoded/home/runnerreferences with\$\{AWF_RUNNER_HOME:-/home/runner}so the fallback preserves existing behavior.src/cli.ts: Add a--runner-home <path>CLI flag as an optional override for cases where auto-detection isn't sufficient.src/docker-manager.ts: Construct the whitelisted$HOMEsubdirs dynamically using the resolved runner home path.src/docker-manager.test.tsverifying that a non-defaultHOMEvalue propagates correctly through the generated Docker Compose config.