Skip to content

Instantly share code, notes, and snippets.

@roelven
Created July 23, 2025 11:14
Show Gist options
  • Save roelven/8efcb6fc31432978e30643aed79e9191 to your computer and use it in GitHub Desktop.
Save roelven/8efcb6fc31432978e30643aed79e9191 to your computer and use it in GitHub Desktop.

πŸš€ Claude Code Quick Start Guide

πŸ“‹ What We're Building

A professional Claude Code environment using:

  • Docker for isolated development environments
  • Node.js 24 for running Claude Code
  • Git for version control, zsh for better UX
  • Claude Code Router for more cost-effective agentic coding
  • CLAUDE.md for persistent memory between sessions
  • Non-root user setup to enable --dangerously-skip-permissions mode

Why Non-Root Setup?

Claude Code's --dangerously-skip-permissions flag allows Claude to modify files more freely, which is essential for effective development work. However, this flag only works when Claude Code runs as a non-root user for security reasons. Our setup creates a claude user specifically for this purpose.

Benefits of --dangerously-skip-permissions mode:

  • Claude can create, modify, and delete files as needed
  • No permission prompts that might interrupt the development flow
  • More natural development experience
  • Essential for complex refactoring and file operations

🎯 PART 1: Get Claude Running (30 minutes)

Step 1: Install Docker Desktop

  1. Download: https://www.docker.com/products/docker-desktop/

  2. Install:

    • βœ… Enable WSL 2
    • βœ… Add desktop shortcut
  3. Restart your computer

  4. Verify: Open your terminal and run:

    docker --version

Step 2: Create Claude Docker Image

2.1 Start Fresh Ubuntu Container

In your terminal:

docker run -it --name claude-dev-container ubuntu:24.04 bash

2.2 Create and Run Setup Script

Instead of manually running commands, we'll create a script for reliability:

2.2.1 Create the setup script:

Create a new file called claude-setup.sh in any directory you prefer, then copy the script content below into it.

2.2.2 Create claude-setup.sh file with this content:

#!/bin/bash
set -e  # Exit on any error

echo "πŸš€ Starting Claude Container setup..."

# Update system
echo "πŸ“¦ Updating system packages..."
apt update && apt upgrade -y

# Install essential tools including sudo
echo "πŸ”§ Installing essential tools..."
apt install -y curl git ripgrep nano wget zsh sudo

# Create claude user with sudo privileges
echo "πŸ‘€ Creating claude user..."
useradd -m -s /bin/zsh -G sudo claude
echo "claude:claude" | chpasswd

# Allow claude user to sudo without password (for container convenience)
echo "claude ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

# Install Node.js 24 (Latest LTS) - system-wide
echo "πŸ“‹ Installing Node.js 24..."
curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
apt install -y nodejs

# Switch to claude user for the rest of setup
echo "πŸ”„ Switching to claude user setup..."
sudo -u claude bash << 'USER_SETUP'
cd /home/claude

# Install Oh My Zsh
echo "🎨 Installing Oh My Zsh..."
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended

# Install Antigen for zsh plugin management
echo "πŸ”Œ Installing Antigen..."
curl -L git.io/antigen > /home/claude/antigen.zsh

# Configure npm for global packages
echo "βš™οΈ Configuring npm..."
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'

# Configure zsh with advanced settings
echo "🎯 Configuring zsh..."
cat > ~/.zshrc << 'EOF'
# Path to your oh-my-zsh installation.
export ZSH="$HOME/.oh-my-zsh"

# Load Antigen
source $HOME/antigen.zsh

# Load the oh-my-zsh's library.
antigen use oh-my-zsh

# Bundles from the default repo (robbyrussell's oh-my-zsh).
antigen bundle git
antigen bundle command-not-found
antigen bundle zsh-users/zsh-autosuggestions
antigen bundle zsh-users/zsh-syntax-highlighting
antigen bundle lukechilds/zsh-nvm

# Apply antigen configuration
antigen apply

# Add npm global path
export PATH="$HOME/.npm-global/bin:$PATH"

# Set zsh as default theme
ZSH_THEME="robbyrussell"

# Initialize oh-my-zsh
source $ZSH/oh-my-zsh.sh
EOF

# Configure git for Claude
echo "πŸ€– Configuring git for Claude..."
git config --global user.name "Claude Code"
git config --global user.email "[email protected]"
git config --global init.defaultBranch main

# Set up commit template for Claude
cat > ~/.gitmessage << 'GIT_TEMPLATE'


πŸ€– Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
GIT_TEMPLATE

git config --global commit.template ~/.gitmessage

# Create global Claude rules file
echo "πŸ“ Setting up global Claude rules..."
cat > ~/.claude-rules << 'CLAUDE_RULES'
# Claude Development Rules

## Workflow Requirements

### Process Flow
- **ASK FIRST**: When missing information or context before starting implementation, always ask the user for clarification
- **TDD SEQUENCE**: Always follow this exact sequence: write test β†’ create code β†’ verify all tests pass β†’ git commit
- **USE FULL PATHS**: When executing commands, always use full paths, never relative paths. Do not assume you're in the project directory

### Testing Constraints
- **10-SECOND TIMEOUT**: All unit tests must have timeouts. Test suites must not exceed 10 seconds total runtime
- **NO STUCK TESTS**: Implement timeouts to prevent AI agent from getting stuck on hanging tests

## Code Standards

### File Constraints
- **200-300 LINE LIMIT**: Refactor any file exceeding 300 lines
- **NO INLINE SCRIPTS**: Never write one-off scripts directly in project files

### Clean Code Mantra
Write code as if the person maintaining it is a violent psychopath who knows where you live:
- **NO CLEVER TRICKS**: Clear, obvious code only
- **COMMENT THE WHY**: Only explain why, never what. Code shows what
- **MEASURE THEN OPTIMIZE**: No premature optimization
- **SIMPLICITY FIRST**: Remove everything non-essential

### Refactoring Rules
- **EDIT DON'T COPY**: Modify existing files directly. Never duplicate files and rename them (e.g., `component-v2.tsx`)
- **STAY IN SCOPE**: Stay within the defined project scope, do not execute programs outside

### Logging Workflow
- **ADD DURING DEBUG**: Add logs during implementation/debugging phases
- **REMOVE WHEN STABLE**: Remove debugging logs once code is working and stable
CLAUDE_RULES

# Source the new zsh configuration and install Claude Code
echo "πŸ”„ Loading zsh configuration..."
source ~/.zshrc

echo 'πŸ“¦ Installing Claude Code Router...'
npm install -g @musistudio/claude-code-router

echo 'βš™οΈ Configuring Claude Code Router...'
mkdir -p ~/.claude-code-router/
cat > ~/.claude-code-router/config.json << 'CONFIG_EOF'
{
  "Providers": [
    {
      "name": "deepseek",
      "api_base_url": "https://api.deepseek.com/chat/completions",
      "api_key": "YOUR_DEEPSEEK_API_KEY_HERE",
      "models": ["deepseek-chat", "deepseek-reasoner"],
      "transformer": {
        "use": ["deepseek"],
        "deepseek-chat": {
          "use": ["tooluse"]
        }
      }
    },
    {
      "name": "gemini",
      "api_base_url": "https://generativelanguage.googleapis.com/v1beta/models/",
      "api_key": "YOUR_GEMINI_API_KEY_HERE",
      "models": ["gemini-2.5-flash"],
      "transformer": {
        "use": ["gemini"]
      }
    }
  ],
  "Router": {
    "default": "deepseek,deepseek-chat",
    "background": "gemini-2.5-flash",
    "think": "deepseek,deepseek-reasoner",
    "longContext": "deepseek-reasoner"
  },
  "HOST": "0.0.0.0"
}
CONFIG_EOF

echo 'πŸ“¦ Installing Claude Code...'
npm install -g @anthropic-ai/claude-code

echo 'βœ… Verifying installation...'
ccr code --version
echo 'πŸŽ‰ Setup complete! Claude Code with Claude Code Router is ready to use.'

USER_SETUP

πŸ”‘ API Keys Required: Before running the script, you'll need to:

  1. Get your DeepSeek API key from https://platform.deepseek.com/
  2. Get your Gemini API key from https://console.cloud.google.com/
  3. Replace YOUR_DEEPSEEK_API_KEY_HERE and YOUR_GEMINI_API_KEY_HERE in the script

2.2.3 Run the setup script in your container:

# Start container with script mounted
docker run -it --name claude-dev-container -v "$(pwd):/setup" ubuntu:24.04 bash

# Inside container, navigate and make script executable  
cd /setup
chmod +x claude-setup.sh
./claude-setup.sh

# After setup completes, the claude user will be ready
# Exit as root, then re-enter as claude user to test
exit

2.2.4 Test the claude user setup:

# Re-enter container as claude user to verify everything works
docker start claude-dev-container
docker exec -it -u claude claude-dev-container zsh

# Test Claude Code installation
source ~/.zshrc
ccr code --version
exit

The script will automatically:

  • βœ… Install all dependencies
  • βœ… Create claude user with proper permissions
  • βœ… Configure Oh My Zsh with advanced plugins for the claude user
  • βœ… Set up npm global packages in user space
  • βœ… Install and verify Claude Code for non-root usage
  • βœ… Configure zsh as the default shell for claude user

2.2.5 Verify installation: When logged in as the claude user, you should see:

βœ… Verifying installation...
claude-code v1.x.x
πŸŽ‰ Setup complete! Claude Code with Claude Code Router is ready to use.

2.3 Save Your Claude Image

  1. Exit the container:

    exit
  2. Save as reusable image (in your terminal):

    docker commit claude-dev-container claude-container
    docker rm claude-dev-container

Step 3: Test Claude and Project Mounting

Now let's test Claude Code Router and learn how to mount your project folders:

3.1 Basic Test

# Create test directory
mkdir -p ~/claude-test
cd ~/claude-test

# Run Claude Code Router with mounted project
docker run -it --rm -u claude -v "$(pwd):/workspace" claude-container zsh -c "source ~/.zshrc && cd /workspace && ccr code --dangerously-skip-permissions"

3.2 Understanding Project Mounting

Key Concept: The -v flag mounts your local project folder into the container's /workspace directory.

Mounting Pattern:

docker run -it --rm -u claude -v "/path/to/your/project:/workspace" claude-container zsh -c "source ~/.zshrc && cd /workspace && ccr code --dangerously-skip-permissions"

Examples:

# Mount current directory
docker run -it --rm -u claude -v "$(pwd):/workspace" claude-container zsh -c "source ~/.zshrc && cd /workspace && ccr code --dangerously-skip-permissions"

# Mount specific project folder
docker run -it --rm -u claude -v "~/my-projects/web-app:/workspace" claude-container zsh -c "source ~/.zshrc && cd /workspace && ccr code --dangerously-skip-permissions"

🎯 What happens:

  • Your local project files appear in the container's /workspace directory
  • Changes made in the container are reflected in your local files
  • Claude can read and modify your project files directly
  • All work persists on your local machine

πŸŽ‰ If you see Claude's interface, you're ready to code!

Step 4: Create a Shortcut (Recommended)

Instead of typing the long docker command every time, create a simple shortcut:

Add to your shell profile (choose your shell):

# For bash users - add to ~/.bashrc
echo 'alias claude-container="docker run -it --rm -u claude -v \"\$(pwd):/workspace\" claude-container zsh -c \"source ~/.zshrc && cd /workspace && ccr code --dangerously-skip-permissions\""' >> ~/.bashrc
source ~/.bashrc

# For zsh users - add to ~/.zshrc  
echo 'alias claude-container="docker run -it --rm -u claude -v \"\$(pwd):/workspace\" claude-container zsh -c \"source ~/.zshrc && cd /workspace && ccr code --dangerously-skip-permissions\""' >> ~/.zshrc
source ~/.zshrc

Now you can simply run:

cd ~/projects/my-project
claude-container

πŸ“ PART 2: Project Structure and Git Integration (15 minutes)

Step 1: Create Your Projects Structure

# Create main projects folder
mkdir -p ~/projects
cd ~/projects

Step 2: Create Your First Project

# Create and initialize a new project
mkdir my-first-project
cd my-first-project
git init
echo "# My First Project" > README.md
git add README.md
git commit -m "Initial commit"

Step 3: Add CLAUDE.md (Essential!)

Create the CLAUDE.md file that serves as Claude's memory between sessions:

# Create CLAUDE.md with the template from Part 3 below
touch CLAUDE.md

🧠 PART 3: The CLAUDE.md System - Claude's Memory

Why CLAUDE.md is Critical

Without CLAUDE.md: Every Claude session starts from zero. You'll repeat explanations, lose context, and waste time.

With CLAUDE.md: Claude remembers everything between sessions - your progress, decisions, and next steps.

Essential CLAUDE.md Template

Create this file in EVERY project:

# [Project Name] - Claude Development Guide

## 🎯 Project Mission
[One sentence describing what we're building and why]

## πŸ“Š Current Status
- **Version**: 0.1.0
- **Last Session**: [Date]
- **Next Priority**: [What to work on next]

## πŸ”₯ Active Tasks (Current Session)
Working on:
- [ ] Current task

## πŸ“‹ Master Task List

### High Priority
- [ ] Task 1
- [ ] Task 2

### Medium Priority
- [ ] Task 3
- [ ] Task 4

### Completed βœ…
- [x] Set up project (Date)

## πŸ—οΈ Project Structure
project/
β”œβ”€β”€ src/
β”œβ”€β”€ tests/
β”œβ”€β”€ CLAUDE.md      <-- You are here
└── README.md

## πŸ’‘ Key Decisions & Context
- **Why we chose X**: [Reasoning]
- **Important constraint**: [Details]

## πŸ”§ Technical Notes
- **API Endpoint**: https://api.example.com
- **Database**: PostgreSQL
- **Key Dependencies**: express, postgres

## πŸ“ Session Notes

### Session [Date]
- Completed: [What we did]
- Discovered: [Problems/insights]
- Next time: [What to do next]

## 🚨 Claude Instructions

1. ALWAYS read this file first when starting
2. Update task lists as we complete items
3. Add new discoveries to session notes
4. Ask for clarification if anything is unclear

Working with CLAUDE.md

Starting Each Session

For ongoing projects:

# Navigate to your project
cd ~/projects/my-project

# Start claude container with our shortcut
claude-container

First prompt to Claude:

Read both ~/.claude-rules and CLAUDE.md to understand our global standards and project context. What should we work on today based on our priorities?

During Your Session

  • "Let's update CLAUDE.md with our progress"
  • "What new tasks should we add to CLAUDE.md?"
  • "Please document this decision in CLAUDE.md"

Ending Your Session

Final prompt:

Update CLAUDE.md with:
1. Tasks we completed (move to Completed section)
2. New tasks we discovered
3. Session notes with key decisions
4. What we should work on next time

Then please commit our changes with an appropriate commit message.

Claude can now commit directly:

git add .
git commit -m "Update project: [Claude's description of work done]"
# Automatically includes the Claude Code signature

πŸ’‘ Benefits of Claude making commits:

  • Professional Attribution: Each Claude commit includes clear branding and co-authorship
  • Seamless workflow: No need to exit container
  • Detailed messages: Claude can write comprehensive commit messages
  • Real-time commits: Commit after each significant change
  • Clear history: git log shows exactly which changes were made by Claude vs you

What this provides:

  • Clear branding: Links back to Claude Code
  • Proper attribution: Shows Claude as co-author
  • Professional appearance: Clean, recognizable format
  • GitHub integration: Co-authored-by is recognized by GitHub

Example commit history:

* a1b2c3d - Add user authentication system (Claude Assistant)
* d4e5f6g - Fix navbar styling issues (Your Name)
* g7h8i9j - Update CLAUDE.md: completed auth module (Claude Assistant)
* j0k1l2m - Initial project setup (Your Name)

πŸš€ PART 4: Advanced Memory Techniques

1. Code Markers for Context

In your code files, add:

// CLAUDE-CONTEXT: This handles user authentication
// CLAUDE-TODO: Add rate limiting here
// CLAUDE-CAREFUL: Security-critical - don't modify without review

Reference these in CLAUDE.md:

## Code Markers
- Look for CLAUDE-TODO markers for quick tasks
- CLAUDE-CONTEXT explains complex sections
- CLAUDE-CAREFUL marks security-sensitive code

2. Decision Log

Add to CLAUDE.md:

## Architecture Decisions

### 2024-03-15: Chose PostgreSQL over MongoDB
- **Reason**: Need ACID compliance for financial data
- **Trade-off**: Less flexible schema
- **Mitigation**: Using JSONB columns for flexibility

3. Progress Tracking

## Project Milestones
- [x] Phase 1: Basic Setup (Week 1)
- [x] Phase 2: Core Features (Week 2-3)
- [ ] Phase 3: Testing (Week 4)
- [ ] Phase 4: Deployment (Week 5)

Current Phase: 2 (60% complete)

4. Context Preservation

## Important Context
- **Client Requirement**: Must work offline
- **Performance Target**: <100ms response time
- **Browser Support**: Chrome, Firefox, Safari (no IE)
- **Mobile**: Responsive, not native

5. Session Continuity

Always end CLAUDE.md with:

## πŸ”„ Next Session Setup
1. First, run: `npm install` (if any new dependencies)
2. Check tests: `npm test`
3. Continue with: [Specific task]
4. Watch out for: [Any gotchas]

πŸ”§ Quick Troubleshooting

Claude Code Router command not found

source ~/.zshrc
# or
export PATH="$HOME/.npm-global/bin:$PATH"

Permission denied errors

If you get permission errors when running Claude Code:

  • Make sure you're using the -u claude flag in your Docker command
  • Verify the --dangerously-skip-permissions flag is included
  • Check that the claude user owns the necessary files

Container name already in use

docker rm claude-dev-container
# Then create new container

Project files not appearing in container

  • Check your mount path: -v "$(pwd):/workspace"
  • Ensure you're in the correct local directory
  • Verify container is using /workspace as working directory
  • Make sure you're using the claude user: -u claude

🎯 Key Takeaways

  1. CLAUDE.md is NOT optional - It's Claude's brain between sessions
  2. Non-root user required - Use -u claude flag for --dangerously-skip-permissions mode
  3. Claude commits directly - Configured as "Claude Assistant" for clear attribution
  4. Be specific in CLAUDE.md - Vague notes = confused Claude
  5. Master project mounting - Use -v "$(pwd):/workspace" to mount your project
  6. One project = One container - Keep projects isolated
  7. Always mount your project folder - Claude needs access to your files
  8. Use skip permissions flag - --dangerously-skip-permissions enables full file operations
  9. Professional Attribution - Claude commits include clear branding and co-authorship

πŸ“Š Setup Checklist

  • Docker Desktop installed and running
  • Claude Docker image created (claude-container)
  • Projects folder created (~/projects)
  • First project with CLAUDE.md created
  • Successfully ran Claude Code Router with mounted project
  • Understand how to mount different project folders
  • Know how to commit changes with git

Ready to build amazing things with Claude! πŸš€

@roelven
Copy link
Author

roelven commented Jul 23, 2025

End result of an artefact created with Claude: https://claude.ai/public/artifacts/034317f2-3bd8-416a-bab7-6466446a2b4c

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