Skip to content

Instantly share code, notes, and snippets.

@sinabahram
Created August 30, 2025 18:36
Show Gist options
  • Select an option

  • Save sinabahram/15403652e92bea5e7662272f4cbcf46a to your computer and use it in GitHub Desktop.

Select an option

Save sinabahram/15403652e92bea5e7662272f4cbcf46a to your computer and use it in GitHub Desktop.
ClaudeBox WSL2 Root User Support - Fix for Docker build failure with UID 0

ClaudeBox WSL2 Root User Fix

This gist contains the necessary changes to support running ClaudeBox as root (UID 0) in WSL2.

File 1: build/Dockerfile

Key changes:

  • Lines 29-40: Handle user creation when UID=0 by creating symlink instead
  • Lines 48-53: Create helper script for conditional command execution
  • Throughout: Use helper script for user-context commands
@@ -26,9 +26,20 @@ ENV LANG=en_US.UTF-8 \
     LANGUAGE=en_US:en \
     LC_ALL=en_US.UTF-8
 
-RUN groupadd -g $GROUP_ID $USERNAME || true && \
-    useradd -m -u $USER_ID -g $GROUP_ID -s /bin/bash $USERNAME
+# Handle user creation - special case for root (UID=0)
+RUN if [ "$USER_ID" = "0" ]; then \
+        # Running as root - create home directory structure for consistency \
+        mkdir -p /home/$USERNAME && \
+        # Create a symlink from /root to /home/claude for consistency \
+        rm -rf /home/$USERNAME && \
+        ln -s /root /home/$USERNAME; \
+    else \
+        # Normal user creation \
+        groupadd -g $GROUP_ID $USERNAME || true && \
+        useradd -m -u $USER_ID -g $GROUP_ID -s /bin/bash $USERNAME; \
+    fi
 
 RUN ARCH=$(dpkg --print-architecture) && \
     wget -q -O /tmp/git-delta_${DELTA_VERSION}_${ARCH}.deb \
         https://github.com/dandavison/delta/releases/download/${DELTA_VERSION}/git-delta_${DELTA_VERSION}_${ARCH}.deb && \
     dpkg -i /tmp/git-delta_${DELTA_VERSION}_${ARCH}.deb && \
     rm /tmp/git-delta_${DELTA_VERSION}_${ARCH}.deb
 
-USER $USERNAME
+# Use a shell script to handle conditional user switching
+RUN echo '#!/bin/bash\n\
+if [ "'$USER_ID'" != "0" ]; then\n\
+    exec su - '$USERNAME' -c "$@"\n\
+else\n\
+    exec bash -c "$@"\n\
+fi' > /tmp/run_as_user.sh && chmod +x /tmp/run_as_user.sh
+
+# Set working directory
 WORKDIR /home/$USERNAME
 
-RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v1.2.0/zsh-in-docker.sh)" -- \
+# Install zsh-in-docker for the appropriate user
+RUN /tmp/run_as_user.sh 'sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v1.2.0/zsh-in-docker.sh)" -- \
     -p git \
     -p fzf \
     # ... rest of zsh config
+    -x'

Additional changes throughout the Dockerfile:

  • Replace all RUN commands that need user context with /tmp/run_as_user.sh
  • Remove USER directive since we handle this in the entrypoint
  • Ensure sudoers entry is only created for non-root users

File 2: build/docker-entrypoint

Key changes:

  • Add root detection and helper function
  • Fix shell script issues (remove local outside functions)
  • Handle exec calls with explicit conditionals
@@ -6,6 +6,24 @@ export PATH="/home/DOCKERUSER/.local/bin:$PATH"
 # Also set PATH for runuser commands
 export RUNUSER_PATH="/home/DOCKERUSER/.local/bin:$PATH"
 
+# Check if we're running as root (UID 0)
+IS_ROOT=false
+if [ "$(id -u)" = "0" ]; then
+    IS_ROOT=true
+fi
+
+# Helper function to run commands as the appropriate user
+run_as_user() {
+    if [ "$IS_ROOT" = "true" ]; then
+        # When running as root, just execute directly
+        "$@"
+    else
+        # When not root, use runuser
+        runuser -u DOCKERUSER -- "$@"
+    fi
+}
+
 ENABLE_SUDO=false
 DISABLE_FIREWALL=false
 SHELL_MODE=false
@@ -98,14 +116,14 @@ if [[ "${SHELL_MODE}" == "true" ]]; then
             # Try to acquire lock for venv creation
-            if runuser -u DOCKERUSER -- mkdir -p "$(dirname "$VENV_FLAG")" && runuser -u DOCKERUSER -- mkdir "$VENV_FLAG.lock" 2>/dev/null; then
+            if run_as_user mkdir -p "$(dirname "$VENV_FLAG")" && run_as_user mkdir "$VENV_FLAG.lock" 2>/dev/null; then
                 # Lock acquired, create venv if needed
                 if [ ! -d "$VENV_DIR" ]; then
-                    PATH="/home/DOCKERUSER/.local/bin:$PATH" runuser -u DOCKERUSER -- uv venv --python-preference managed "$VENV_DIR" || true
+                    PATH="/home/DOCKERUSER/.local/bin:$PATH" run_as_user uv venv --python-preference managed "$VENV_DIR" || true
                 fi
                 
                 # Remove lock and create flag to indicate completion
-                runuser -u DOCKERUSER -- rmdir "$VENV_FLAG.lock"
-                runuser -u DOCKERUSER -- touch "$VENV_FLAG"
+                run_as_user rmdir "$VENV_FLAG.lock"
+                run_as_user touch "$VENV_FLAG"
             else
                 # Someone else is creating it, wait for completion flag
-                local wait_count=0
+                wait_count=0
                 while [ ! -f "$VENV_FLAG" ] && [ $wait_count -lt 60 ]; do

For exec calls that can't use the helper function:

@@ -250,7 +268,11 @@ if [[ "${SHELL_MODE}" == "true" ]]; then
         chmod +x /tmp/tmux-init.sh
         sed -i "s|DOCKERUSER|$DOCKERUSER|g" /tmp/tmux-init.sh
-        exec runuser -u DOCKERUSER -- bash -c "source /home/DOCKERUSER/.nvm/nvm.sh && cd /workspace && exec tmux new-session /tmp/tmux-init.sh"
+        if [ "$IS_ROOT" = "true" ]; then
+            exec bash -c "source /home/DOCKERUSER/.nvm/nvm.sh && cd /workspace && exec tmux new-session /tmp/tmux-init.sh"
+        else
+            exec runuser -u DOCKERUSER -- bash -c "source /home/DOCKERUSER/.nvm/nvm.sh && cd /workspace && exec tmux new-session /tmp/tmux-init.sh"
+        fi
     else
         # For non-tmux, show logo before starting shell
-        exec runuser -u DOCKERUSER -- bash -c "..."
+        if [ "$IS_ROOT" = "true" ]; then
+            exec bash -c "..."
+        else
+            exec runuser -u DOCKERUSER -- bash -c "..."
+        fi

Summary

These changes allow ClaudeBox to run successfully when the host user is root (UID 0) in WSL2 environments. The fix:

  1. Avoids trying to create a user with UID 0 (which would conflict with root)
  2. Creates a symlink from /home/claude to /root for path consistency
  3. Handles command execution appropriately based on whether running as root
  4. Fixes shell script issues that prevented proper execution

The changes are minimal and focused on supporting this specific use case without affecting normal operation for non-root users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment