# Wakel AI Instance Deployment Architecture

## Overview

Wakel AI uses a **direct Docker + nginx reverse proxy** architecture for deploying isolated customer instances on subdomains. This approach was chosen over full Dokploy installation due to port conflicts with existing nginx configuration.

## Architecture Components

```
┌─────────────────────────────────────────────────────────────────────────┐
│                          Incoming Request                                │
│                    http://subdomain.wakelai.com                         │
└────────────────────────────┬────────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         nginx (Port 80/443)                             │
│                    /etc/nginx/conf.d/00-wakelai.com.conf                 │
│                                                                         │
│  - Wildcard subdomain handling: *.wakelai.com                           │
│  - Routes to specific backend ports based on subdomain                  │
│  - HTTP access for instances (HTTPS pending wildcard SSL)               │
└────────────────────────────┬────────────────────────────────────────────┘
                             │
        ┌────────────────────┼────────────────────┐
        ▼                    ▼                    ▼
┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│ Main Next.js │    │   Instance   │    │   Instance   │
│   Backend    │    │  Container   │    │  Container   │
│   Port 9100  │    │  Port 9500+  │    │  Port 9501+  │
└──────────────┘    └──────────────┘    └──────────────┘
```

## Key Components

### 1. Docker Network
- **Name**: `wakelai-runtime`
- **Purpose**: Isolated network for instance containers
- **Creation**: `docker network create wakelai-runtime`

### 2. Instance Containers
Each instance gets:
- Unique container name: `{instanceId}-{appName}`
- Dedicated host port from range 9500+ (avoiding conflicts with main app on 9100)
- Connected to `wakelai-runtime` network
- Environment variables for instance configuration

Example container creation:
```bash
docker run -d \
  --name test2-o45wo-hermes \
  --network wakelai-runtime \
  -p 9500:4860 \
  -e INSTANCE_NAME=test2-o45wo \
  -e DOMAIN=wakelai.com \
  ghcr.io/hostinger/hvps-hermes-agent:latest
```

### 3. nginx Configuration
Main config: `/etc/nginx/conf.d/00-wakelai.com.conf`

Key features:
- **Wildcard subdomain support**: `server_name *.wakelai.com;`
- **HTTP backend proxy** for main app (port 9100)
- **Instance-specific proxies** (to be added dynamically)

Current structure:
```nginx
# Main domain (HTTPS with SSL redirect)
server {
    listen 80;
    server_name wakelai.com www.wakelai.com;
    return 301 https://$server_name$request_uri;
}

# Subdomains (HTTP - wildcard SSL pending)
server {
    listen 80;
    server_name *.wakelai.com;
    location / {
        proxy_pass http://127.0.0.1:9100;
        # proxy headers...
    }
}

# Main HTTPS server
server {
    listen 443 ssl http2;
    server_name wakelai.com www.wakelai.com *.wakelai.com;
    # SSL config...
    # Main app proxy to port 9100
}
```

### 4. DNS Configuration
Zone file: `/var/named/wakelai.com.db`

Wildcard record:
```
* 3600 IN A 203.161.35.97
```

This ensures `*.wakelai.com` resolves to the server IP.

## Environment Variables

Required in `.env.local`:
```bash
# Application URLs
NEXT_PUBLIC_APP_URL=https://wakelai.com
NEXTAUTH_URL=https://wakelai.com

# Database
DATABASE_URL=postgresql://wakelai:wakelai_password@localhost:55433/wakelai?schema=public

# Domain Configuration
APP_ROOT_DOMAIN=wakelai.com

# Docker Configuration
HERMES_DOCKER_NETWORK=wakelai-runtime
HERMES_IMAGE=ghcr.io/hostinger/hvps-hermes-agent:latest
HERMES_INTERNAL_PORT=4860

# Dokploy Settings (legacy - may be removed)
DOKPLOY_API_MODE=local-docker
```

## Instance Deployment Flow

### Current Implementation (Proven Working)

1. **User creates instance** via dashboard
2. **Instance record created** in database with:
   - Unique subdomain (e.g., `test2-o45wo`)
   - Random ID
   - Status: "creating"

3. **Docker container provisioned**:
   ```bash
   docker run -d \
     --name {instanceId}-hermes \
     --network wakelai-runtime \
     -p {assignedPort}:4860 \
     -e INSTANCE_NAME={subdomain} \
     -e DOMAIN=wakelai.com \
     ghcr.io/hostinger/hvps-hermes-agent:latest
   ```

4. **nginx configuration created** (if implementing dynamic routing):
   ```bash
   # Create /etc/nginx/conf.d/instance-{subdomain}.conf
   server {
       listen 80;
       server_name {subdomain}.wakelai.com;
       location / {
           proxy_pass http://127.0.0.1:{assignedPort};
           # proxy headers...
       }
   }
   nginx -s reload
   ```

5. **Instance accessible** at `http://{subdomain}.wakelai.com`

### Current Limitation

All subdomains currently route to the main Next.js app (port 9100) because:
1. SSL certificate only covers `wakelai.com` and `www.wakelai.com`
2. No wildcard SSL certificate for `*.wakelai.com`
3. Instance containers are created but not yet routed with dedicated nginx configs

## Port Allocation Strategy

- **Main Next.js App**: 9100
- **Instance Range**: 9500-9999 (50 instances max)
- **Buffer**: 10000+ for future expansion

## SSL/TLS Considerations

### Current State
- SSL certificate covers: `wakelai.com`, `www.wakelai.com`
- **Does NOT cover**: `*.wakelai.com` (wildcard)
- Subdomains accessible via HTTP only

### Future Enhancement
Obtain wildcard SSL certificate:
```bash
certbot certonly --manual --preferred-challenges dns \
  -d '*.wakelai.com' -d 'wakelai.com'
```

## Migration from Dokploy

The application includes Dokploy-based code (`src/lib/dokploy.ts`) that was designed for:
- API mode deployment to external Dokploy server
- Local docker mode with docker-compose generation

**Decision**: Use direct Docker deployment instead due to:
1. Port conflicts (Dokploy wants port 80)
2. nginx already handles reverse proxy
3. Simpler architecture with fewer dependencies

The Dokploy code can be:
- Kept as reference
- Removed entirely
- Adapted to use direct Docker CLI

## Next Steps

1. **Implement dynamic nginx config generation**
   - API endpoint to create/delete instance-specific nginx configs
   - Integrate with instance creation/deletion flow

2. **Port management**
   - Track assigned ports in database
   - Implement port allocation/pool system

3. **Wildcard SSL**
   - Obtain wildcard certificate
   - Enable HTTPS for all instance subdomains

4. **Container management**
   - Implement proper container lifecycle (start/stop/restart)
   - Add container health monitoring

## Commands Reference

### Docker
```bash
# Create network
docker network create wakelai-runtime

# Run instance container
docker run -d --name {name} --network wakelai-runtime -p {port}:4860 {image}

# Stop/start container
docker stop {name}
docker start {name}

# Remove container
docker rm {name}

# List containers
docker ps
docker ps -a  # including stopped
```

### nginx
```bash
# Test configuration
nginx -t

# Reload configuration
nginx -s reload

# Create instance config
cat > /etc/nginx/conf.d/instance-{subdomain}.conf << 'EOF'
server {
    listen 80;
    server_name {subdomain}.wakelai.com;
    location / {
        proxy_pass http://127.0.0.1:{port};
        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;
    }
}
EOF

# Remove instance config
rm /etc/nginx/conf.d/instance-{subdomain}.conf
nginx -s reload
```

### Database
```bash
# Connect
psql -U wakelai -d wakelai -p 55433

# Check instances
SELECT id, name, subdomain, domain, status, created_at FROM "Instance";
```

## Files Reference

| File | Purpose |
|------|---------|
| `.env.local` | Environment configuration |
| `src/lib/dokploy.ts` | Legacy Dokploy integration code |
| `src/components/dashboard/instance-actions.tsx` | Instance control UI (deploy/start/stop/delete) |
| `src/app/api/instances/[id]/route.ts` | Instance API endpoints |
| `/etc/nginx/conf.d/00-wakelai.com.conf` | Main nginx configuration |
| `/var/named/wakelai.com.db` | DNS zone file |

## Testing

### Verify DNS
```bash
# Using Google DNS
nslookup test-wakelai.wakelai.com 8.8.8.8

# Expected output should show:
# test-wakelai.wakelai.com canonical name = *.wakelai.com
# Name: *.wakelai.com
# Address: 203.161.35.97
```

### Verify nginx
```bash
curl -I http://test-wakelai.wakelai.com
# Should return 200 if routed correctly
```

### Verify Docker
```bash
docker inspect <container-name> | grep IPAddress
# Should show container is on wakelai-runtime network
```
