🤖 fix: support Docker images with non-root default users - #1587
Conversation
Images like codercom/enterprise-base and codercom/example-base run as a non-root user (e.g., 'coder' with uid 1000) by default. Previously, DockerRuntime failed with 'Permission denied' when trying to: 1. Create /src and /var/mux/plans directories during workspace init 2. Create ~/.mux-tmp/... temp directories during streaming (resolved to /root which non-root users cannot write to) Changes: - Detect container's default user (uid/gid/home) after container creation - Create workspace directories as root, then chown to container user - Resolve ~ paths using detected home instead of hardcoded /root This fix is safe for existing workspaces: - No migration required - workspace config entries unchanged - Container names derived the same way (getContainerName) - Existing containers not modified on upgrade - For root-based images: behavior unchanged (uid=0, home=/root) - For non-root images: ~ now correctly resolves to user's home The user detection runs in ensureReady() so existing workspaces automatically get correct ~ resolution on next use.
There was a problem hiding this comment.
💡 Codex Review
mux/src/node/runtime/DockerRuntime.ts
Lines 1003 to 1006 in 1d83d09
In forkWorkspace, the destination container is only prepared for /var/mux, then git clone is executed into /src as the container’s default user. On images that default to a non-root user (the newly supported scenario), /src typically doesn’t exist and the user can’t create top-level directories, so the clone fails with Permission denied. createWorkspace now fixes this by creating /src as root and chowning it, but the fork path doesn’t mirror that, so forks of non-root images will still fail.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
forkWorkspace was only creating /var/mux/plans as root, then relying on git clone to create /src. But on non-root images, the container user cannot create top-level directories, so the clone fails. Now mirrors createWorkspace: create /src as root and chown before clone.
|
@codex review Fixed the forkWorkspace issue: now creating |
|
Codex Review: Didn't find any major issues. Keep it up! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Problem
Docker images like
codercom/enterprise-baseandcodercom/example-baserun as a non-root user by default (e.g.,coderwith uid 1000). Previously, DockerRuntime failed with "Permission denied" errors:During workspace creation:
During streaming (after workspace created):
Root Cause
mkdir /srcandmkdir /var/mux/plansran as the container's default user, which doesn't have permission to create top-level directories~was hardcoded to resolve to/root, but non-root users can't write thereSolution
id -u,id -g,echo $HOMEdocker exec --user root, thenchownto the container user~paths using the detected home directory instead of hardcoded/rootImages That Now Work
codercom/enterprise-basecoder(1000)codercom/example-basecoder(1000)node:20,ubuntu, etc.root(0)Why This Is Safe (No Migration Required)
chownor restructure existing containersensureReady()detects user info when container starts, so existing workspaces automatically get correct~resolution on next useTesting
Tested with
codercom/example-base:latest:/home/coder/.mux-tmp/...)/srcGenerated with
mux• Model:anthropic:claude-opus-4-5• Thinking:high• Cost:$3.77