This gist contains the necessary changes to support running ClaudeBox as root (UID 0) in WSL2.
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
RUNcommands 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
Key changes:
- Add root detection and helper function
- Fix shell script issues (remove
localoutside 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 ]; doFor 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 "..."
+ fiThese changes allow ClaudeBox to run successfully when the host user is root (UID 0) in WSL2 environments. The fix:
- Avoids trying to create a user with UID 0 (which would conflict with root)
- Creates a symlink from /home/claude to /root for path consistency
- Handles command execution appropriately based on whether running as root
- 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.