Upload files to "/"

This commit is contained in:
Zac Gaetano 2026-04-04 14:34:56 -04:00
parent 5881d0f0df
commit 068e6e9f5e
5 changed files with 1747 additions and 2 deletions

504
DEPLOYMENT_GUIDE.md Normal file
View file

@ -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+

419
QUICKSTART.md Normal file
View file

@ -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! 🚀

342
README.md
View file

@ -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. ## 📦 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+

318
deploy-ssh.sh Normal file
View file

@ -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_IP> [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 "$@"

166
nginx.conf Normal file
View file

@ -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;
}
}
}