Claude CLI Docker Integration Success Guide
Generated: 2025-08-10 UTC
Purpose: Guide for successfully integrating Claude CLI in Docker/Sliplane environments
Status: Complete Implementation
Objective
Successfully integrate Claude CLI into a Dockerized application deployed on Sliplane, ensuring proper workspace management and environment configuration.
Prerequisites
- Docker application with Node.js 20-alpine base image
- Sliplane deployment account
- Claude CLI package (@anthropic-ai/claude-code)
- SSH access to Sliplane containers
Implementation Steps
Step 1: Dockerfile Configuration
# Install Claude CLI globally and set up properly
RUN npm install -g @anthropic-ai/claude-code@latest && \
ln -sf $(npm root -g)/@anthropic-ai/claude-code/cli.js /usr/local/bin/claude && \
chmod +x /usr/local/bin/claude && \
claude --version || echo "Claude CLI installation verification failed"
# Create Claude config directory and symlink projects to workspaces
RUN mkdir -p /home/nodejs/.claude && \
ln -s /app/workspaces /home/nodejs/.claude/projects && \
chown -R nodejs:nodejs /home/nodejs/.claude
# Environment variables
ENV RUNNING_IN_DOCKER=true \
USE_DOCKER_WORKSPACE=true \
WORKSPACES_PATH=/app/workspaces \
CLAUDE_PROJECTS_PATH=/app/workspaces \
CLAUDE_HOME=/home/nodejs/.claude
Step 2: Docker Entrypoint Script
Create docker-entrypoint.sh:
#!/bin/bash
# Ensure environment variables are set
export RUNNING_IN_DOCKER="${RUNNING_IN_DOCKER:-true}"
export USE_DOCKER_WORKSPACE="${USE_DOCKER_WORKSPACE:-true}"
export WORKSPACES_PATH="${WORKSPACES_PATH:-/app/workspaces}"
export CLAUDE_PROJECTS_PATH="${CLAUDE_PROJECTS_PATH:-/app/workspaces}"
export CLAUDE_HOME="${CLAUDE_HOME:-/home/nodejs/.claude}"
# Create necessary directories
mkdir -p "$WORKSPACES_PATH"
mkdir -p "$CLAUDE_HOME"
# Create symlink so Claude CLI uses our workspace directory
if [ -d "$CLAUDE_HOME/projects" ] && [ ! -L "$CLAUDE_HOME/projects" ]; then
if [ "$(ls -A $CLAUDE_HOME/projects 2>/dev/null)" ]; then
cp -r $CLAUDE_HOME/projects/* "$WORKSPACES_PATH/" 2>/dev/null || true
fi
rm -rf "$CLAUDE_HOME/projects"
fi
if [ ! -e "$CLAUDE_HOME/projects" ]; then
ln -s "$WORKSPACES_PATH" "$CLAUDE_HOME/projects"
echo "β
Symlink created: $CLAUDE_HOME/projects -> $WORKSPACES_PATH"
fi
# Execute main command
exec "$@"
Step 3: Code Updates
workspace-manager.js
export async function setupOrganizationWorkspace(userId, organizationData, projectId = null) {
// Use WORKSPACES_PATH if in Docker, otherwise use HOME directory
const baseWorkspacePath = process.env.WORKSPACES_PATH || path.join(process.env.HOME, '.claude/projects');
let workspacePath;
if (projectId && organizationData.searchTerm) {
const sanitizedName = organizationData.searchTerm.toLowerCase()
.replace(/[^a-z0-9]/g, '-')
.replace(/-+/g, '-')
.replace(/^-|-$/g, '')
.substring(0, 30);
workspacePath = path.join(baseWorkspacePath, `${sanitizedName}-${projectId}`);
} else {
workspacePath = path.join(baseWorkspacePath, 'default-workspace');
}
// ... rest of function
}
claude-cli.js
// Simplified Docker detection - rely on environment variable
const isDockerEnv = process.env.RUNNING_IN_DOCKER === 'true';
// Handle workspace paths
let workingDir = cwd || process.cwd();
if (!workingDir.startsWith('/')) {
if (process.env.WORKSPACES_PATH) {
workingDir = path.join(process.env.WORKSPACES_PATH, workingDir);
} else {
workingDir = path.resolve(workingDir);
}
}
Step 4: Verification Scripts
Create scripts/verify-claude-deployment.sh:
#!/bin/bash
echo "π Claude CLI Deployment Verification"
# Check environment variables
check_env_var() {
local var_name=$1
local var_value="${!var_name}"
if [ -n "$var_value" ]; then
echo "β
$var_name: $var_value"
else
echo "β $var_name: Not set"
fi
}
check_env_var "RUNNING_IN_DOCKER"
check_env_var "WORKSPACES_PATH"
check_env_var "CLAUDE_PROJECTS_PATH"
# Check Claude CLI
if command -v claude &> /dev/null; then
echo "β
Claude CLI found at: $(which claude)"
claude --version
else
echo "β Claude CLI not found"
fi
# Check symlink
if [ -L "/home/nodejs/.claude/projects" ]; then
echo "β
Symlink exists: $(readlink /home/nodejs/.claude/projects)"
else
echo "β Symlink missing"
fi
Key Issues Solved
1. Multiple Workspace Directories
Problem: Claude CLI created projects in /home/nodejs/.claude/projects/ while app used /app/workspaces/
Solution: Created symlink from Claude's project directory to app workspace directory
2. Environment Detection
Problem: Complex multi-layered Docker detection logic
Solution: Simplified to single RUNNING_IN_DOCKER=true check
3. Path Resolution
Problem: Inconsistent path resolution between services
Solution: Standardized on WORKSPACES_PATH environment variable
Verification Checklist
- Build Docker image with updated Dockerfile
- Deploy to Sliplane
- SSH into container:
ssh -p 22222 service_xxx@server.sliplane.app - Run verification script:
./scripts/verify-claude-deployment.sh - Check symlink:
ls -la /home/nodejs/.claude/ | grep projects - Test Claude CLI:
claude --version - Verify single workspace:
ls -la /app/workspaces/
Final Architecture
/app/workspaces/ # Main workspace directory
βββ workspace/ # Default workspace
β βββ CLAUDE.md # Project configuration
β βββ docs/ # Documentation structure
βββ [other-projects]/ # Additional workspaces
/home/nodejs/.claude/
βββ projects -> /app/workspaces # Symlink to workspaces
βββ sessions/ # Claude sessions
βββ claude.json # Claude configuration
Deployment Commands
# Build image
docker build -f Dockerfile.sliplane -t myapp:latest .
# Push to registry
docker push myregistry/myapp:latest
# Deploy to Sliplane
curl -X POST "https://api.sliplane.io/deploy/service_id/secret?tag=latest"
# Verify deployment
ssh -p 22222 service_xxx@server.sliplane.app
./scripts/verify-claude-deployment.sh
Lessons Learned
- Symlinks are critical for unifying workspace locations
- Simple environment detection is more reliable than complex logic
- docker-entrypoint.sh ensures runtime configuration
- Verification scripts are essential for deployment validation
- Documentation of the solution prevents future issues
References
- Claude CLI Documentation
- Sliplane Documentation
- Alpine Linux Node.js Best Practices
- Docker Multi-stage Builds
Result: Successfully integrated Claude CLI in Docker/Sliplane environment with unified workspace management and proper environment configuration.