# Multi-Tenant Dobby Deployment

Run 3 isolated Dobby instances on a single VPS, each with its own Claude Code auth, Slack bot, and public URL.

## Architecture

```
              Cloudflare Tunnel
                    │
       ┌────────────┼────────────┐
       ▼            ▼            ▼
  tenant1.dom  tenant2.dom  tenant3.dom
       │            │            │
  :8420         :8421        :8422
       │            │            │
  ┌────┴───┐   ┌────┴───┐   ┌────┴───┐
  │ dobby  │   │ dobby  │   │ dobby  │
  │ slack  │   │ slack  │   │ slack  │
  │ claude │   │ claude │   │ claude │
  └────────┘   └────────┘   └────────┘
```

Each container runs:
- Dobby daemon (unique port)
- Slack bot (if tokens provided)
- Claude Code CLI (for interactive auth)

## Quick Start

### 1. Run setup script on VPS

```bash
# SSH into VPS
ssh root@<vps-ip>

# Download and run setup
curl -fsSL https://raw.githubusercontent.com/simonucl/dobby/main/deploy/multi-tenant/setup.sh | bash
```

Or manually:
```bash
mkdir -p /mnt/data/dobby
git clone https://github.com/simonucl/dobby.git /mnt/data/dobby/repo
cd /mnt/data/dobby/repo/deploy/multi-tenant
bash setup.sh
```

### 2. Configure each tenant

Edit env files with Slack tokens and API keys:

```bash
cd /mnt/data/dobby/repo/deploy/multi-tenant
nano tenant1.env
nano tenant2.env
nano tenant3.env
```

### 3. Build and start

```bash
docker compose build
docker compose up -d
```

### 4. Authenticate Claude Code

Each tenant needs to authenticate Claude Code interactively:

```bash
docker exec -it dobby-tenant1 claude
# Follow the OAuth flow in your browser

docker exec -it dobby-tenant2 claude
docker exec -it dobby-tenant3 claude
```

### 5. Set up Cloudflare Tunnel

On the VPS host (not in containers):

```bash
# Install cloudflared
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | gpg --dearmor -o /usr/share/keyrings/cloudflare-main.gpg
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/cloudflared.list
apt-get update && apt-get install -y cloudflared

# Authenticate and create tunnel
cloudflared tunnel login
cloudflared tunnel create dobby-multi

# Add DNS routes (replace with your domain)
cloudflared tunnel route dns dobby-multi tenant1.dobby.example.com
cloudflared tunnel route dns dobby-multi tenant2.dobby.example.com
cloudflared tunnel route dns dobby-multi tenant3.dobby.example.com

# Copy and edit the config
cp cloudflared-config.yml.example /etc/cloudflared/config.yml
nano /etc/cloudflared/config.yml  # Fill in TUNNEL_ID and domains

# Start tunnel
cloudflared tunnel run dobby-multi
```

### 6. Connect spokes

From each tenant's local machine:

```bash
pip install dobby-orchestrator
dobby agent --hub https://tenant1.dobby.example.com --id my-mac
```

## Management

### View logs

```bash
# Container logs
docker logs -f dobby-tenant1

# Internal logs
docker exec dobby-tenant1 cat /data/logs/daemon.log
docker exec dobby-tenant1 cat /data/logs/slack.log
```

### Restart a tenant

```bash
docker compose restart tenant1
```

### Update Dobby

```bash
cd /mnt/data/dobby/repo
git pull
cd deploy/multi-tenant
docker compose build
docker compose up -d
```

### Access dashboard

Each tenant's dashboard is available at their subdomain:
- `https://tenant1.dobby.example.com/dashboard`
- `https://tenant2.dobby.example.com/dashboard`
- `https://tenant3.dobby.example.com/dashboard`

## File Layout on VPS

```
/mnt/data/dobby/
├── repo/                          # Dobby git repo
│   └── deploy/multi-tenant/
│       ├── docker-compose.yml
│       ├── Dockerfile
│       ├── entrypoint.sh
│       ├── tenant1.env            # Tenant 1 secrets (gitignored)
│       ├── tenant2.env            # Tenant 2 secrets
│       └── tenant3.env            # Tenant 3 secrets
├── tenant1/
│   ├── data/                      # Dobby data (db, results, logs)
│   └── claude/                    # Claude Code auth (~/.claude)
├── tenant2/
│   ├── data/
│   └── claude/
└── tenant3/
    ├── data/
    └── claude/
```

## Adding More Tenants

1. Add a new service block in `docker-compose.yml` (copy tenant3, change port to 8423)
2. Create `tenant4.env.example` and `tenant4.env`
3. Add directory: `mkdir -p /mnt/data/dobby/tenant4/{data/results,data/logs,claude}`
4. Add DNS route: `cloudflared tunnel route dns dobby-multi tenant4.dobby.example.com`
5. Update cloudflared config with new ingress rule
6. `docker compose up -d tenant4`
