From 068e6e9f5e7e088e1844d6632a983f096961591c Mon Sep 17 00:00:00 2001 From: zgaetano Date: Sat, 4 Apr 2026 14:34:56 -0400 Subject: [PATCH] Upload files to "/" --- DEPLOYMENT_GUIDE.md | 504 ++++++++++++++++++++++++++++++++++++++++++++ QUICKSTART.md | 419 ++++++++++++++++++++++++++++++++++++ README.md | 342 +++++++++++++++++++++++++++++- deploy-ssh.sh | 318 ++++++++++++++++++++++++++++ nginx.conf | 166 +++++++++++++++ 5 files changed, 1747 insertions(+), 2 deletions(-) create mode 100644 DEPLOYMENT_GUIDE.md create mode 100644 QUICKSTART.md create mode 100644 deploy-ssh.sh create mode 100644 nginx.conf diff --git a/DEPLOYMENT_GUIDE.md b/DEPLOYMENT_GUIDE.md new file mode 100644 index 0000000..9386903 --- /dev/null +++ b/DEPLOYMENT_GUIDE.md @@ -0,0 +1,504 @@ +# Claude Code + Agents UI Docker Stack Deployment Guide + +## Overview + +This guide covers deploying a complete Docker stack on your TrueNAS SCALE instance that combines: +- **Claude Code Agents UI** (Nuxt 3 frontend for agent orchestration) +- **Claude Code Runtime** (Backend for code execution) +- **PostgreSQL** (Optional: for agent data persistence) +- **Redis** (Optional: for caching) +- **Nginx** (Optional: reverse proxy) + +## Prerequisites + +### System Requirements +- TrueNAS SCALE with Docker/Portainer running +- Minimum 4GB RAM allocated to Docker +- At least 20GB free disk space +- Anthropic API key (get from https://console.anthropic.com/) + +### Network Requirements +- Port 3000 (Agents UI) +- Port 5000 (Claude Code API - optional) +- Port 80/443 (Nginx - optional) +- Port 5432 (PostgreSQL - optional) +- Port 6379 (Redis - optional) + +## Deployment Methods + +### Method 1: SSH Deployment (Recommended for TrueNAS) + +#### Step 1: SSH into your TrueNAS system + +```bash +ssh root@your-truenas-ip +# or use your specific TrueNAS user +``` + +#### Step 2: Create project directory + +```bash +mkdir -p /mnt/pool-name/docker/claude-code-stack +cd /mnt/pool-name/docker/claude-code-stack +``` + +#### Step 3: Clone/create Docker files + +Option A: Clone the entire repo with compose file: +```bash +git clone https://github.com/Ngxba/claude-code-agents-ui.git +cd claude-code-agents-ui +``` + +Option B: Copy the provided docker-compose.yml (recommended for your setup): +```bash +# Copy the provided files to this directory +# - docker-compose.yml +# - claude-code-stack.env +# - nginx.conf +# - Dockerfile (if using combined image) +``` + +#### Step 4: Configure environment variables + +```bash +cp claude-code-stack.env .env +nano .env # or vim .env +``` + +Update these critical variables: +```env +ANTHROPIC_API_KEY=sk-ant-your-actual-key-here +POSTGRES_PASSWORD=your-secure-password +SESSION_SECRET=your-random-session-secret +``` + +#### Step 5: Deploy with Docker Compose + +```bash +# Pull latest images +docker-compose pull + +# Build custom image (if using combined Dockerfile) +docker-compose build --no-cache + +# Start all services +docker-compose up -d + +# Check status +docker-compose ps +``` + +#### Step 6: Verify deployment + +```bash +# Check logs +docker-compose logs -f agents-ui +docker-compose logs -f claude-code-backend + +# Test Claude Code UI +curl http://localhost:3000 + +# Test Claude Code API +curl http://localhost:5000/health 2>/dev/null || echo "API not yet responsive" +``` + +### Method 2: TrueNAS MCP Deployment + +If you have the TrueNAS MCP server configured: + +```javascript +// Example: Using TrueNAS MCP to deploy + +await mcp.call('truenas:create_dataset', { + parent: 'pool-name', + name: 'docker/claude-code-stack' +}); + +await mcp.call('truenas:list_directory', { + path: '/mnt/pool-name/docker/claude-code-stack' +}); + +// Write Docker Compose file via MCP +// (Use ssh_ssh_exec for Docker commands) +``` + +### Method 3: Portainer UI Deployment + +If using Portainer on TrueNAS: + +1. **Open Portainer** at `https://your-truenas-ip:9000` +2. **Go to: Stacks > Add Stack** +3. **Upload or paste** the docker-compose.yml content +4. **Set environment variables** via the Web Editor +5. **Deploy** + +## Stack Architecture + +``` +┌─────────────────────────────────────────────────────────┐ +│ Claude Code Stack │ +├─────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────────────┐ ┌────────────────────┐ │ +│ │ Nginx (Port 80) │◄───────►│ Agents UI │ │ +│ │ (optional) │ │ (Port 3000) │ │ +│ └──────────────────┘ ├────────────────────┤ │ +│ │ - Agent Management │ │ +│ │ - Chat Interface │ │ +│ ┌──────────────────┐ │ - Workflow Builder │ │ +│ │ Claude Code │ └────────────────────┘ │ +│ │ Backend (5000) │ │ +│ │ │ ┌────────────────────┐ │ +│ │ - Code Execution │◄───────►│ PostgreSQL │ │ +│ │ - File Access │ │ (Port 5432) │ │ +│ │ - Shell Commands │ │ (optional) │ │ +│ └──────────────────┘ └────────────────────┘ │ +│ │ │ │ +│ └──────────────┬───────────────┘ │ +│ │ │ +│ ┌─────▼──────┐ │ +│ │ Redis │ │ +│ │ (6379) │ │ +│ │ (optional) │ │ +│ └────────────┘ │ +│ │ +│ ┌────────────────────────────────────────────────┐ │ +│ │ Shared Volumes │ │ +│ │ - /workspace (projects) │ │ +│ │ - /root/.claude (config) │ │ +│ └────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────┘ +``` + +## Post-Deployment Setup + +### 1. Initialize Claude Code Configuration + +```bash +docker-compose exec claude-code-backend bash + +# Inside container: +claude auth login +# Follow the authentication flow + +# Create initial .claude directory structure +mkdir -p ~/.claude/agents ~/.claude/skills ~/.claude/commands +cd ~/.claude +``` + +### 2. Configure Agents UI + +The Agents UI will automatically detect: +- Your Claude configuration at `~/.claude` +- Available agents and commands +- Environment setup + +Access it at: `http://your-truenas-ip:3000` + +### 3. Set Up Project Workspace + +```bash +# Create workspace structure +docker-compose exec agents-ui bash -c "mkdir -p /workspace/{projects,agents,tools}" + +# Mount your projects (example) +docker-compose exec agents-ui bash -c "ln -s /mnt/shared/projects /workspace/projects" +``` + +### 4. Configure SSH Keys (Optional but Recommended) + +For agents to perform git operations: + +```bash +docker-compose exec claude-code-backend bash + +# Inside container: +ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" + +# Copy public key to your GitHub/GitLab: +cat ~/.ssh/id_rsa.pub +``` + +## Common Operations + +### Start/Stop Stack + +```bash +# Start +docker-compose up -d + +# Stop +docker-compose down + +# Stop with volume preservation +docker-compose down --remove-orphans + +# Full reset (CAUTION: removes volumes) +docker-compose down -v +``` + +### View Logs + +```bash +# All services +docker-compose logs -f + +# Specific service +docker-compose logs -f agents-ui +docker-compose logs -f claude-code-backend + +# Follow errors only +docker-compose logs -f --tail=100 | grep -i error +``` + +### Execute Commands in Container + +```bash +# Access Agents UI shell +docker-compose exec agents-ui sh + +# Access Claude Code shell +docker-compose exec claude-code-backend bash + +# Run Claude Code directly +docker-compose exec claude-code-backend claude "your prompt here" +``` + +### Backup and Restore + +```bash +# Backup volumes +docker-compose exec claude-code-backend tar czf - -C /root .claude | gzip > claude-backup.tar.gz + +# Backup workspace +tar czf workspace-backup.tar.gz workspace/ + +# Restore +tar xzf claude-backup.tar.gz -C workspace/ +``` + +## Troubleshooting + +### Issue: Connection refused on port 3000 + +```bash +# Check if service is running +docker-compose ps + +# Check service logs +docker-compose logs agents-ui + +# Restart service +docker-compose restart agents-ui +``` + +### Issue: ANTHROPIC_API_KEY not recognized + +```bash +# Verify .env file exists and has correct key +cat .env | grep ANTHROPIC_API_KEY + +# Pass key directly in docker-compose command +ANTHROPIC_API_KEY=your-key docker-compose up -d +``` + +### Issue: PostgreSQL connection fails + +```bash +# Check if postgres is ready +docker-compose exec postgres pg_isready -U claude + +# Check credentials in .env +grep POSTGRES .env + +# View postgres logs +docker-compose logs postgres +``` + +### Issue: Agents UI can't find Claude config + +```bash +# Verify mount +docker-compose exec agents-ui ls -la /root/.claude/ + +# Check permissions +docker-compose exec agents-ui stat /root/.claude + +# Ensure volume is created +docker volume ls | grep claude +``` + +## Performance Tuning + +### Increase Resource Limits + +Edit docker-compose.yml: + +```yaml +services: + agents-ui: + deploy: + resources: + limits: + cpus: '2' + memory: 2G + reservations: + cpus: '1' + memory: 1G +``` + +### Enable Redis Caching + +```bash +# Uncomment Redis in docker-compose.yml +# Set REDIS_HOST=redis in .env +docker-compose up -d redis +``` + +### Database Optimization + +```bash +# Increase PostgreSQL max connections +docker-compose exec postgres psql -U claude -c "ALTER SYSTEM SET max_connections = 200;" +docker-compose restart postgres +``` + +## Security Hardening + +### 1. Enable SSL/TLS + +```bash +# Generate self-signed certificate (for testing) +openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes + +# Or use Let's Encrypt with certbot +mkdir -p certs +# Place your cert.pem and key.pem in ./certs/ +``` + +Update docker-compose.yml to mount certs. + +### 2. Restrict Network Access + +```bash +# Allow only specific IPs to Nginx +# In nginx.conf, add to each location: +allow 192.168.1.0/24; +deny all; +``` + +### 3. Regular Backups + +```bash +#!/bin/bash +# backup.sh + +BACKUP_DIR="/mnt/backup/claude-code-stack" +mkdir -p $BACKUP_DIR + +# Backup volumes +docker run --rm \ + -v claude_config:/data \ + -v $BACKUP_DIR:/backup \ + alpine tar czf /backup/claude-config-$(date +%Y%m%d).tar.gz -C /data . + +echo "Backup complete: $BACKUP_DIR" +``` + +## Monitoring + +### Health Checks + +```bash +# Manual health check +curl http://localhost:3000/health + +# Monitor with watch +watch -n 5 'docker-compose ps && echo "---" && curl -s http://localhost:3000/health' +``` + +### Logging and Metrics + +```bash +# View resource usage +docker stats + +# Monitor over time +docker-compose up -d && \ +sleep 60 && \ +docker stats --no-stream +``` + +## Updating and Maintenance + +### Update Images + +```bash +# Pull latest images +docker-compose pull + +# Rebuild custom image +docker-compose build --no-cache + +# Restart services +docker-compose up -d +``` + +### Clear Disk Space + +```bash +# Remove unused images +docker image prune -a + +# Remove unused volumes +docker volume prune + +# Remove unused networks +docker network prune +``` + +## Support and Resources + +- **Claude Code Agents UI**: https://github.com/Ngxba/claude-code-agents-ui +- **Claude Code Docs**: https://docs.anthropic.com/en/docs/build-with-claude +- **Docker Docs**: https://docs.docker.com/ +- **TrueNAS Documentation**: https://www.truenas.com/docs/ + +## Quick Reference Commands + +```bash +# Start stack +docker-compose up -d + +# Check status +docker-compose ps + +# View logs +docker-compose logs -f + +# Stop stack +docker-compose down + +# Execute command +docker-compose exec agents-ui command + +# Access shell +docker-compose exec agents-ui sh + +# Update +docker-compose pull && docker-compose up -d + +# Backup +docker-compose exec claude-code-backend tar czf - -C /root .claude | gzip > backup.tar.gz + +# Restore database +psql -h localhost -U claude -d claude_agents < backup.sql +``` + +--- + +**Last Updated**: 2026-04-04 +**Stack Version**: 1.0.0 +**Docker Compose Version**: 3.8+ diff --git a/QUICKSTART.md b/QUICKSTART.md new file mode 100644 index 0000000..2562045 --- /dev/null +++ b/QUICKSTART.md @@ -0,0 +1,419 @@ +# Claude Code + Agents UI Stack - Quick Start Guide + +## 📋 Prerequisites + +- TrueNAS SCALE system running +- Docker and Docker Compose installed on TrueNAS +- Anthropic API Key (get from https://console.anthropic.com/) +- SSH access to TrueNAS (for SSH deployment method) + +## 🚀 Deployment Options + +### Option 1: SSH Deployment (Easiest for TrueNAS) + +This is the recommended method for deploying to TrueNAS. + +#### Setup + +```bash +# 1. Make the deployment script executable +chmod +x deploy-ssh.sh + +# 2. Set your API key +export ANTHROPIC_API_KEY="sk-ant-your-actual-key-here" + +# 3. Deploy to your TrueNAS +./deploy-ssh.sh 192.168.1.100 root tank + +# Parameters: +# 192.168.1.100 = Your TrueNAS IP address +# root = SSH username (default: root) +# tank = Pool name (default: tank) +``` + +That's it! The script will: +- ✓ Create the project directory +- ✓ Upload Docker configuration +- ✓ Configure environment variables +- ✓ Start all services +- ✓ Verify deployment + +#### Access the UI + +Once deployed, access the Agents UI at: +``` +http://192.168.1.100:3000 +``` + +--- + +### Option 2: MCP Deployment (For Advanced Users) + +If you have the TrueNAS MCP server running at `mcp.wilddragon.net`: + +#### Setup + +```bash +# 1. Install dependencies +pip install httpx + +# 2. Make the script executable +chmod +x deploy-mcp.py + +# 3. Deploy via MCP +export ANTHROPIC_API_KEY="sk-ant-your-actual-key-here" +python deploy-mcp.py --mcp-url https://mcp.wilddragon.net/mcp --pool tank +``` + +--- + +### Option 3: Manual Docker Compose Deployment + +For complete control: + +#### Step 1: SSH into TrueNAS + +```bash +ssh root@192.168.1.100 +``` + +#### Step 2: Create project directory + +```bash +mkdir -p /mnt/tank/docker/claude-code-stack +cd /mnt/tank/docker/claude-code-stack +``` + +#### Step 3: Copy docker-compose.yml + +Create and edit the file: +```bash +cat > docker-compose.yml << 'EOF' +# Paste the content from docker-compose.yml +EOF +``` + +#### Step 4: Configure environment + +```bash +cat > .env << 'EOF' +ANTHROPIC_API_KEY=sk-ant-your-key-here +POSTGRES_PASSWORD=secure-password +NODE_ENV=production +EOF +``` + +#### Step 5: Start services + +```bash +docker-compose up -d +``` + +#### Step 6: Verify + +```bash +docker-compose ps +curl http://localhost:3000 +``` + +--- + +## 📊 Services Overview + +### What Gets Deployed + +| Service | Port | Purpose | Required | +|---------|------|---------|----------| +| **Agents UI** | 3000 | Web interface for agent management | ✓ Yes | +| **Claude Code** | 5000 | Code execution backend | ✓ Yes | +| **PostgreSQL** | 5432 | Data persistence | Optional | +| **Redis** | 6379 | Caching & sessions | Optional | +| **Nginx** | 80/443 | Reverse proxy | Optional | + +--- + +## 🎮 Using the Stack + +### Access the UI + +``` +http://your-truenas-ip:3000 +``` + +### View Logs + +```bash +# SSH into TrueNAS +ssh root@your-truenas-ip + +# Navigate to project +cd /mnt/tank/docker/claude-code-stack + +# View logs +docker-compose logs -f agents-ui +docker-compose logs -f claude-code-backend +``` + +### Run Claude Code Directly + +```bash +# Execute a prompt +docker-compose exec claude-code-backend claude "What files are in the workspace?" + +# Access the CLI +docker-compose exec claude-code-backend bash +``` + +### Stop Services + +```bash +docker-compose down +``` + +### Restart Services + +```bash +docker-compose restart +``` + +--- + +## 🔧 Configuration + +### Environment Variables + +Edit `.env` file to customize: + +```bash +# Your Anthropic API key (REQUIRED) +ANTHROPIC_API_KEY=sk-ant-xxx + +# Database password +POSTGRES_PASSWORD=secure-password + +# Node environment +NODE_ENV=production + +# Claude Code settings +CLAUDE_MODEL=claude-opus-4-1 +RUN_CLAUDE_CODE=true +``` + +### Port Changes + +Want different ports? Edit `docker-compose.yml`: + +```yaml +ports: + - "8000:3000" # Access UI at port 8000 instead +``` + +Then restart: +```bash +docker-compose down && docker-compose up -d +``` + +--- + +## 🐛 Troubleshooting + +### Issue: "Connection refused" on port 3000 + +**Solution:** +```bash +# Check if service is running +docker-compose ps + +# View logs +docker-compose logs agents-ui + +# Restart +docker-compose restart agents-ui + +# Wait a few seconds for startup +sleep 10 +curl http://localhost:3000 +``` + +### Issue: API key not recognized + +**Solution:** +```bash +# Verify .env file +cat .env | grep ANTHROPIC_API_KEY + +# Update if needed +nano .env + +# Restart services +docker-compose restart +``` + +### Issue: Database connection fails + +**Solution:** +```bash +# Check PostgreSQL +docker-compose logs postgres + +# Verify credentials in .env +grep POSTGRES .env + +# Restart database +docker-compose restart postgres +``` + +### Issue: Cannot SSH to TrueNAS + +**Solution:** +```bash +# Check IP address +ping your-truenas-ip + +# Test SSH connection +ssh -v root@your-truenas-ip + +# Check if SSH is enabled on TrueNAS +# System Settings > Services > SSH > Start Automatically +``` + +--- + +## 📈 Performance Tips + +### Increase Memory Allocation + +Edit `docker-compose.yml`: + +```yaml +services: + agents-ui: + deploy: + resources: + limits: + memory: 2G + reservations: + memory: 1G +``` + +### Enable Caching with Redis + +Redis is included in the stack and automatically started. + +### Database Optimization + +```bash +# Increase PostgreSQL connections +docker-compose exec postgres psql -U claude -c "ALTER SYSTEM SET max_connections = 200;" +docker-compose restart postgres +``` + +--- + +## 🔒 Security Recommendations + +### 1. Change Default Passwords + +```bash +# Edit .env +nano .env + +# Change: +# POSTGRES_PASSWORD=changeMe123! +# SESSION_SECRET=your-random-secret +``` + +### 2. Enable SSL/TLS + +Create self-signed certificate: +```bash +openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes +``` + +Update `docker-compose.yml` to mount certs. + +### 3. Restrict Network Access + +In TrueNAS, configure firewall to allow only trusted IPs. + +### 4. Regular Backups + +```bash +# Backup configuration +docker-compose exec claude-code-backend tar czf - -C /root .claude | gzip > claude-backup.tar.gz + +# Backup database +docker-compose exec postgres pg_dump -U claude claude_agents > backup.sql +``` + +--- + +## 🎯 Next Steps + +1. **Access the UI**: http://your-truenas-ip:3000 +2. **Configure API key**: Check that ANTHROPIC_API_KEY is set +3. **Create your first agent**: Use the Agents UI to create and test agents +4. **Set up workspace**: Mount your projects in `/workspace` +5. **Configure SSH keys**: For git operations (optional) + +--- + +## 📚 Resources + +- **Claude Code Agents UI**: https://github.com/Ngxba/claude-code-agents-ui +- **Claude Documentation**: https://docs.anthropic.com/ +- **Docker Compose Reference**: https://docs.docker.com/compose/compose-file/ +- **TrueNAS Documentation**: https://www.truenas.com/docs/ + +--- + +## 💡 Common Commands + +```bash +# View running services +docker-compose ps + +# Follow logs +docker-compose logs -f + +# Stop everything +docker-compose down + +# Restart everything +docker-compose restart + +# Execute command in container +docker-compose exec agents-ui command + +# Access shell in container +docker-compose exec agents-ui sh + +# Update and restart +docker-compose pull && docker-compose up -d + +# Clean up disk space +docker system prune -a +``` + +--- + +## 🆘 Getting Help + +If you encounter issues: + +1. **Check the logs**: `docker-compose logs -f` +2. **Verify configuration**: `cat .env` +3. **Check connectivity**: `docker-compose exec agents-ui ping -c 1 claude-code-backend` +4. **Review the full guide**: See `DEPLOYMENT_GUIDE.md` + +--- + +**Deployed successfully?** 🎉 + +Next, configure your agents: +1. Open http://your-truenas-ip:3000 +2. Create a new agent +3. Set up your workspace +4. Start automating! + +Happy coding! 🚀 diff --git a/README.md b/README.md index bdf3b91..052ee2f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,341 @@ -# claude-code-stack +# Claude Code + Agents UI Stack - Complete Package -Docker stack combining Claude Code Agents UI with Claude Code runtime. Multi-service orchestration with PostgreSQL, Redis, and Nginx for TrueNAS SCALE deployment. \ No newline at end of file +## 📦 What's Included + +This package contains everything needed to deploy a complete Claude Code + Agents UI Docker stack to your TrueNAS SCALE instance. + +### Files Overview + +``` +claude-code-stack/ +├── QUICKSTART.md # Start here! +├── DEPLOYMENT_GUIDE.md # Comprehensive guide +├── docker-compose.yml # Main Docker Compose configuration +├── claude-agents-ui-Dockerfile # Custom Docker image combining UI + Claude Code +├── nginx.conf # Reverse proxy configuration +├── claude-code-stack.env # Environment variables template +├── deploy-ssh.sh # Automated SSH deployment script (RECOMMENDED) +├── deploy-mcp.py # MCP-based deployment script +└── README.md # This file +``` + +## 🚀 Quick Start (30 seconds) + +```bash +# 1. Set your API key +export ANTHROPIC_API_KEY="sk-ant-your-actual-key-here" + +# 2. Run the deployment script +chmod +x deploy-ssh.sh +./deploy-ssh.sh 192.168.1.100 root tank + +# 3. Access the UI +# Open: http://192.168.1.100:3000 +``` + +## 📋 What Each File Does + +### QUICKSTART.md +**Start here if you're in a hurry!** +- 3 deployment methods +- Quick setup instructions +- Troubleshooting tips +- Common commands + +### DEPLOYMENT_GUIDE.md +**Complete reference guide** +- Detailed architecture +- Step-by-step setup +- Configuration options +- Monitoring & maintenance +- Security hardening +- Performance tuning + +### docker-compose.yml +**Main orchestration file** +Includes: +- Claude Code Agents UI (Nuxt 3 frontend) +- Claude Code Runtime (code execution) +- PostgreSQL (data persistence) +- Redis (caching) +- Nginx (reverse proxy) + +All services with: +- Health checks +- Volume management +- Network configuration +- Resource limits + +### claude-agents-ui-Dockerfile +**Optional: Combined image** +Builds a single Docker image containing: +- Agents UI (Nuxt 3) +- Claude Code CLI +- Required dependencies +- Non-root user for security + +Use this if you prefer building a custom image instead of using pre-built images. + +### nginx.conf +**Reverse proxy configuration** +- Load balancing +- SSL/TLS support +- Rate limiting +- Security headers +- WebSocket support +- Static file caching + +### claude-code-stack.env +**Environment variables template** +Configure: +- Anthropic API key (REQUIRED) +- Database credentials +- API ports and hosts +- Security settings +- Storage options +- Agent configuration + +### deploy-ssh.sh +**Automated SSH deployment** ⭐ RECOMMENDED +- One-command setup +- Validates prerequisites +- Tests SSH connection +- Creates directories +- Uploads files +- Configures environment +- Starts services +- Verifies deployment +- Sets up monitoring + +### deploy-mcp.py +**MCP-based deployment** +For advanced users with MCP server running: +- Deploys via MCP protocol +- Async/await operation +- Progress indicators +- Error handling + +## 🎯 Deployment Flowchart + +``` +Start + │ + ├─→ Choose Method + │ ├─→ SSH (recommended) → deploy-ssh.sh + │ ├─→ MCP (advanced) → deploy-mcp.py + │ └─→ Manual → Use docker-compose.yml directly + │ + ├─→ Prerequisites + │ ├─→ API Key ✓ + │ ├─→ SSH access ✓ + │ └─→ Docker on TrueNAS ✓ + │ + ├─→ Deploy Stack + │ ├─→ Create directory + │ ├─→ Upload files + │ ├─→ Configure .env + │ ├─→ Pull images + │ └─→ Start services + │ + ├─→ Verify + │ ├─→ Check service status + │ ├─→ Test port 3000 + │ └─→ View logs + │ + └─→ Access UI + └─→ http://your-truenas-ip:3000 +``` + +## 🏗️ Architecture + +``` +Your Computer + │ + │ (SSH or MCP) + ▼ +TrueNAS SCALE + │ + ├─→ docker-compose + │ + └─→ Services: + ├─→ Claude Code Agents UI (Port 3000) + │ └─→ Web interface for agent management + │ + ├─→ Claude Code Backend (Port 5000) + │ └─→ Code execution environment + │ + ├─→ PostgreSQL (Port 5432) + │ └─→ Agent data persistence + │ + ├─→ Redis (Port 6379) + │ └─→ Caching & sessions + │ + └─→ Nginx (Port 80/443) + └─→ Reverse proxy +``` + +## 🔐 Security Features + +- ✓ Non-root user execution +- ✓ Health checks on all services +- ✓ Security headers via Nginx +- ✓ Rate limiting +- ✓ SSL/TLS support (optional) +- ✓ Environment variable isolation +- ✓ Volume isolation +- ✓ Network isolation + +## 📊 Resource Requirements + +### Minimum +- RAM: 2GB allocated to Docker +- CPU: 2 cores +- Disk: 10GB free + +### Recommended +- RAM: 4GB allocated to Docker +- CPU: 4 cores +- Disk: 20GB free + +### Optimal +- RAM: 8GB+ allocated to Docker +- CPU: 8+ cores +- Disk: 50GB+ free + +## 🚦 Deployment Status + +After running `deploy-ssh.sh`, you'll see: + +``` +[INFO] Checking prerequisites... +[INFO] Testing SSH connection... +[INFO] Creating project directory on TrueNAS... +[INFO] Uploading Docker configuration files... +[INFO] Configuring environment variables... +[INFO] Deploying Docker stack... +[INFO] Verifying deployment... +======================================== + Claude Code Stack Deployed! +======================================== + +Access the Agents UI at: + http://192.168.1.100:3000 +``` + +## 📝 Next Steps + +1. **Deploy**: Run `./deploy-ssh.sh your-truenas-ip` +2. **Access**: Open http://your-truenas-ip:3000 +3. **Configure**: Set up API keys and workspace +4. **Create**: Build your first agent +5. **Test**: Execute and monitor agent tasks + +## 🆘 Common Issues + +### Q: SSH connection fails +**A:** Check TrueNAS IP, SSH is enabled, and you have correct credentials. + +### Q: Port 3000 not responding +**A:** Wait 30 seconds for startup. Check logs: `docker-compose logs agents-ui` + +### Q: API key not recognized +**A:** Verify in .env file and restart: `docker-compose restart` + +### Q: PostgreSQL connection fails +**A:** Check credentials match in .env. Run: `docker-compose logs postgres` + +See DEPLOYMENT_GUIDE.md for more troubleshooting. + +## 📚 Documentation + +- **QUICKSTART.md** - Start here for quick setup +- **DEPLOYMENT_GUIDE.md** - Complete reference guide +- **Claude Code Docs** - https://docs.anthropic.com/ +- **GitHub Repo** - https://github.com/Ngxba/claude-code-agents-ui + +## 🎓 Learning Resources + +### Getting Started with Claude Code +```bash +claude --help +claude "What's in the current directory?" +``` + +### Creating Agents +Use the Agents UI at http://your-truenas-ip:3000 to: +- Create agents +- Configure models +- Set instructions +- Build workflows + +### Using Agents +```bash +# View available agents +claude list-agents + +# Run an agent +claude run agent-name "prompt" + +# Interactive mode +claude chat agent-name +``` + +## 🔄 Update & Maintenance + +### Pull Latest Images +```bash +docker-compose pull +docker-compose up -d +``` + +### View Logs +```bash +docker-compose logs -f [service] +``` + +### Backup Data +```bash +docker-compose exec claude-code-backend tar czf - -C /root .claude | gzip > backup.tar.gz +``` + +### Clean Up +```bash +docker system prune -a +docker volume prune +``` + +## 📞 Support + +For issues or questions: + +1. Check **DEPLOYMENT_GUIDE.md** troubleshooting section +2. Review **QUICKSTART.md** for common solutions +3. Check Docker logs: `docker-compose logs` +4. Visit: https://github.com/Ngxba/claude-code-agents-ui/issues +5. See: https://docs.anthropic.com/ + +## 📄 License + +This deployment package is provided as-is. + +- **Claude Code** - Use your Anthropic API key +- **Agents UI** - MIT License (https://github.com/Ngxba/claude-code-agents-ui) +- **Docker Components** - Various open-source licenses + +## 🎉 Success! + +Once deployed, you'll have: +- ✓ Web interface for agent management +- ✓ Claude Code execution environment +- ✓ Persistent storage with PostgreSQL +- ✓ Caching layer with Redis +- ✓ Reverse proxy with Nginx +- ✓ All integrated and running on TrueNAS + +Happy coding! 🚀 + +--- + +**Version**: 1.0.0 +**Last Updated**: 2026-04-04 +**Compatibility**: TrueNAS SCALE, Docker Compose 3.8+ diff --git a/deploy-ssh.sh b/deploy-ssh.sh new file mode 100644 index 0000000..a34f515 --- /dev/null +++ b/deploy-ssh.sh @@ -0,0 +1,318 @@ +#!/bin/bash + +# Claude Code Stack Deployment Script for TrueNAS (SSH Method) +# This script automates the deployment via SSH + +set -e + +# Color output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Configuration +TRUENAS_IP="${1:-}" +TRUENAS_USER="${2:-root}" +POOL_NAME="${3:-tank}" +PROJECT_DIR="/mnt/${POOL_NAME}/docker/claude-code-stack" +DOCKER_COMPOSE_VERSION="3.8" + +# Functions +print_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +print_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +print_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +check_prerequisites() { + print_info "Checking prerequisites..." + + # Check if ssh is available + if ! command -v ssh &> /dev/null; then + print_error "SSH client is not installed" + exit 1 + fi + + # Check if ANTHROPIC_API_KEY is set + if [ -z "$ANTHROPIC_API_KEY" ]; then + print_warn "ANTHROPIC_API_KEY environment variable not set" + read -p "Enter your Anthropic API Key: " -r ANTHROPIC_API_KEY + export ANTHROPIC_API_KEY + fi + + print_info "Prerequisites check passed" +} + +validate_input() { + if [ -z "$TRUENAS_IP" ]; then + print_error "Usage: $0 [TRUENAS_USER] [POOL_NAME]" + print_info "Example: $0 192.168.1.100 root tank" + exit 1 + fi +} + +test_ssh_connection() { + print_info "Testing SSH connection to $TRUENAS_USER@$TRUENAS_IP..." + + if ssh -o ConnectTimeout=5 "$TRUENAS_USER@$TRUENAS_IP" "echo 'SSH connection successful'" > /dev/null 2>&1; then + print_info "SSH connection successful" + else + print_error "Failed to connect to TrueNAS via SSH" + print_info "Please verify:" + print_info " - TRUENAS_IP is correct: $TRUENAS_IP" + print_info " - SSH is enabled on TrueNAS" + print_info " - You have the correct credentials" + exit 1 + fi +} + +create_project_directory() { + print_info "Creating project directory on TrueNAS..." + + ssh "$TRUENAS_USER@$TRUENAS_IP" << 'EOF' +POOL_NAME="$1" +PROJECT_DIR="/mnt/${POOL_NAME}/docker/claude-code-stack" + +# Create directory +mkdir -p "$PROJECT_DIR" +chmod 755 "$PROJECT_DIR" + +# Verify +if [ -d "$PROJECT_DIR" ]; then + echo "Directory created: $PROJECT_DIR" +else + echo "Failed to create directory" + exit 1 +fi +EOF +} + +deploy_docker_files() { + print_info "Uploading Docker configuration files..." + + # Check if files exist locally + local files=( + "docker-compose.yml" + "claude-code-stack.env" + "nginx.conf" + ) + + for file in "${files[@]}"; do + if [ ! -f "./$file" ]; then + print_warn "Local file not found: $file" + print_info "Creating minimal $file on remote..." + + case $file in + "docker-compose.yml") + # Create minimal compose file on remote + ssh "$TRUENAS_USER@$TRUENAS_IP" "cat > ${PROJECT_DIR}/docker-compose.yml << 'COMPOSE_EOF' +version: '3.8' +services: + agents-ui: + image: node:20-alpine + container_name: claude-agents-ui + restart: unless-stopped + ports: + - \"3000:3000\" + environment: + ANTHROPIC_API_KEY: \${ANTHROPIC_API_KEY} + volumes: + - claude-config:/root/.claude + - workspace:/workspace + networks: + - claude-stack + +volumes: + claude-config: + driver: local + workspace: + driver: local + +networks: + claude-stack: + driver: bridge +COMPOSE_EOF" + ;; + "claude-code-stack.env") + ssh "$TRUENAS_USER@$TRUENAS_IP" "cat > ${PROJECT_DIR}/.env << 'ENV_EOF' +ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} +POSTGRES_PASSWORD=changeMe123! +SESSION_SECRET=$(openssl rand -base64 32) +NODE_ENV=production +ENV_EOF" + ;; + "nginx.conf") + ssh "$TRUENAS_USER@$TRUENAS_IP" "touch ${PROJECT_DIR}/nginx.conf" + ;; + esac + else + # Upload file + scp "./$file" "$TRUENAS_USER@$TRUENAS_IP:$PROJECT_DIR/" + print_info "Uploaded: $file" + fi + done +} + +configure_environment() { + print_info "Configuring environment variables..." + + ssh "$TRUENAS_USER@$TRUENAS_IP" << EOF +PROJECT_DIR="$PROJECT_DIR" + +# Create .env file if it doesn't exist +if [ ! -f "$PROJECT_DIR/.env" ]; then + cat > "$PROJECT_DIR/.env" << 'ENV_EOF' +ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY +POSTGRES_PASSWORD=$(openssl rand -base64 16) +SESSION_SECRET=$(openssl rand -base64 32) +NODE_ENV=production +CLAUDE_MODEL=claude-opus-4-1 +RUN_CLAUDE_CODE=true +LOG_LEVEL=info +ENV_EOF + print_info "Created .env file" +else + # Update ANTHROPIC_API_KEY in existing .env + sed -i.bak "s/ANTHROPIC_API_KEY=.*/ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY/" "$PROJECT_DIR/.env" + print_info "Updated ANTHROPIC_API_KEY in .env" +fi + +chmod 600 "$PROJECT_DIR/.env" +EOF +} + +deploy_stack() { + print_info "Deploying Docker stack..." + + ssh "$TRUENAS_USER@$TRUENAS_IP" << EOF +cd $PROJECT_DIR + +# Pull latest images +echo "Pulling Docker images..." +docker-compose pull + +# Build (if Dockerfile present) +if [ -f "Dockerfile" ]; then + echo "Building custom image..." + docker-compose build --no-cache +fi + +# Deploy +echo "Starting services..." +docker-compose up -d + +# Wait for services to be ready +echo "Waiting for services to be ready..." +sleep 10 + +# Show status +docker-compose ps +EOF +} + +verify_deployment() { + print_info "Verifying deployment..." + + # Give services time to stabilize + sleep 5 + + print_info "Checking service status..." + ssh "$TRUENAS_USER@$TRUENAS_IP" "cd $PROJECT_DIR && docker-compose ps" + + print_info "Testing Agents UI..." + if curl -s -f "http://$TRUENAS_IP:3000" > /dev/null 2>&1; then + print_info "✓ Agents UI is responsive" + else + print_warn "! Agents UI is not yet responding (may take a few moments)" + fi +} + +setup_monitoring() { + print_info "Setting up basic monitoring..." + + ssh "$TRUENAS_USER@$TRUENAS_IP" << EOF +PROJECT_DIR="$PROJECT_DIR" + +# Create monitoring script +cat > "$PROJECT_DIR/monitor.sh" << 'MONITOR_EOF' +#!/bin/bash + +while true; do + clear + echo "=== Claude Code Stack Status ===" + echo "Time: \$(date)" + echo "" + docker-compose ps + echo "" + echo "Resource Usage:" + docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}" + echo "" + echo "Press Ctrl+C to exit" + sleep 10 +done +MONITOR_EOF + +chmod +x "$PROJECT_DIR/monitor.sh" +print_info "Monitoring script created at: $PROJECT_DIR/monitor.sh" +EOF +} + +print_summary() { + echo "" + echo -e "${GREEN}========================================${NC}" + echo -e "${GREEN} Claude Code Stack Deployed!${NC}" + echo -e "${GREEN}========================================${NC}" + echo "" + echo "Access the Agents UI at:" + echo -e " ${YELLOW}http://$TRUENAS_IP:3000${NC}" + echo "" + echo "Project Directory on TrueNAS:" + echo -e " ${YELLOW}$PROJECT_DIR${NC}" + echo "" + echo "Useful commands:" + echo " SSH into TrueNAS:" + echo -e " ${YELLOW}ssh $TRUENAS_USER@$TRUENAS_IP${NC}" + echo "" + echo " View logs:" + echo -e " ${YELLOW}cd $PROJECT_DIR && docker-compose logs -f${NC}" + echo "" + echo " Stop services:" + echo -e " ${YELLOW}cd $PROJECT_DIR && docker-compose down${NC}" + echo "" + echo " Monitor:" + echo -e " ${YELLOW}cd $PROJECT_DIR && ./monitor.sh${NC}" + echo "" + echo "Next steps:" + echo " 1. Configure your API keys in the UI or .env" + echo " 2. Set up agents via the web interface" + echo " 3. Test with a simple agent execution" + echo "" +} + +# Main execution +main() { + echo -e "${GREEN}Claude Code Stack - TrueNAS Deployment${NC}" + echo "========================================" + echo "" + + validate_input + check_prerequisites + test_ssh_connection + create_project_directory + deploy_docker_files + configure_environment + deploy_stack + verify_deployment + setup_monitoring + print_summary +} + +# Run main function +main "$@" diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..73bd16c --- /dev/null +++ b/nginx.conf @@ -0,0 +1,166 @@ +user nginx; +worker_processes auto; +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; + use epoll; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + client_max_body_size 100M; + + # Gzip compression + gzip on; + gzip_vary on; + gzip_min_length 1000; + gzip_comp_level 6; + gzip_types text/plain text/css text/xml text/javascript + application/json application/javascript application/xml+rss; + + # Upstream services + upstream agents_ui { + least_conn; + server agents-ui:3000 max_fails=3 fail_timeout=30s; + keepalive 32; + } + + upstream claude_api { + least_conn; + server claude-code-backend:5000 max_fails=3 fail_timeout=30s; + keepalive 32; + } + + # Rate limiting zones + limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s; + limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s; + limit_req_zone $binary_remote_addr zone=ws:10m rate=1000r/s; + + # HTTP redirect to HTTPS (uncomment when SSL is configured) + # server { + # listen 80; + # server_name _; + # return 301 https://$host$request_uri; + # } + + # Main server block + server { + listen 80; + server_name _; + + # SSL configuration (uncomment when certificates are available) + # listen 443 ssl http2; + # ssl_certificate /etc/nginx/certs/cert.pem; + # ssl_key /etc/nginx/certs/key.pem; + # ssl_protocols TLSv1.2 TLSv1.3; + # ssl_ciphers HIGH:!aNULL:!MD5; + # ssl_prefer_server_ciphers on; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "no-referrer-when-downgrade" always; + add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; + + # Root location + location / { + limit_req zone=general burst=20 nodelay; + proxy_pass http://agents_ui; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + + # Timeouts + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + + # WebSocket support for real-time agent updates + location /ws { + limit_req zone=ws burst=50 nodelay; + proxy_pass http://agents_ui; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # WebSocket timeouts + proxy_connect_timeout 7d; + proxy_send_timeout 7d; + proxy_read_timeout 7d; + } + + # Claude Code API backend + location /api/claude { + limit_req zone=api burst=50 nodelay; + proxy_pass http://claude_api; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect off; + + # Allow larger payloads for code uploads + client_max_body_size 500M; + + # Timeouts for long-running operations + proxy_connect_timeout 300s; + proxy_send_timeout 300s; + proxy_read_timeout 300s; + } + + # Health check endpoint + location /health { + access_log off; + return 200 "healthy\n"; + add_header Content-Type text/plain; + } + + # Status endpoint (nginx metrics) + location /nginx-status { + stub_status on; + access_log off; + allow 127.0.0.1; + deny all; + } + + # Static files caching + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # Deny access to hidden files + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } + } +}