Skip to content

> STATUS: ABANDONED 2026-05-16 — Zoraxy is the production reverse proxy. Kept for design-decision history. See services/zoraxy.md for current setup.

# Recommended: Traefik Proxy Replacement

## Why Traefik over Zoraxy?

Feature | Zoraxy | Traefik
--- | --- | ---
API | ❌ No public API | ✅ Full REST API
SSL | 💬 Manual (Zoraxy Web UI) | 🔥 Auto-Let's Encrypt
Dynamic | ⚠️ Manual config reload | ✅ Hot-reload configs
File watching | ❌ | ✅ Auto-detect changes
Docker integration | ⚠️ Manual | ✅ Native labels
API endpoints | 403 Forbidden | ✅ JSON API everywhere

## Migration Path

### Current setup:

    Zoraxy (192.168.1.4:8000) → Reverse Proxy Rules (Manual Web UI)
    - litellm.nuclide.systems → 192.168.1.40:14000
    - chat.nuclide.systems → 192.168.1.40:14001
    - mcp.nuclide.systems → 192.168.1.40:8080
    - s3.nuclide.systems → Garage:10004

### New setup with Traefik:

    Traefik (public SSL) → Dynamic Router (labels/consul)
    - All services auto-discovered via Docker labels
    - SSL certificates auto-provisioned
    - No manual Zoraxy configuration needed

## Installation

### Step 1: Install Traefik

    # Create Traefik directory
    mkdir -p /opt/stacks/proxy/traefik/{conf,dynamic}

    # Create docker-compose.yml
    cat > /opt/stacks/proxy/traefik/docker-compose.yml << 'EOF'
    version: "3.8"

    services:
      traefik:
        image: traefik:v3.2
        container_name: traefik
        restart: always
        security_opt:
          - no-new-privileges=true
        network_mode: host
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock:ro
          - /opt/stacks/proxy/traefik/conf:/etc/traefik
          - /opt/stacks/proxy/traefik/dynamic:/etc/traefik/dynamic
          - /opt/stacks/proxy/traefik/letsencrypt:/etc/letsencrypt
        command:
          - "--api.insecure=true"
          - "--providers.docker=true"
          - "--providers.docker.exposedbydefault=false"
          - "--entrypoints.web.address=:80"
          - "--entrypoints.websecure.address=:443"
          - "--certificatesresletsencryptemail=admin@nuclide.systems"
          - "--certificatesresletsencryptstorage=/etc/letsencrypt/acme.json"
    EOF

    # Start Traefik
    cd /opt/stacks/proxy/traefik && docker compose up -d

### Step 2: Create Dynamic Configuration

    # Create router rules
    cat > /opt/stacks/proxy/traefik/dynamic/router.yml << 'EOF'
    http:
      routers:
        litellm-router:
          rule: "Host(`litellm.nuclide.systems`)"
          service: litellm-service
          entrypoints:
            - websecure
          tls:
            certresolver: letsencrypt

        chat-router:
          rule: "Host(`chat.nuclide.systems`)"
          service: chat-service
          entrypoints:
            - websecure
          tls:
            certresolver: letsencrypt

        mcp-router:
          rule: "Host(`mcp.nuclide.systems`)"
          service: mcp-service
          entrypoints:
            - websecure
          tls:
            certresolver: letsencrypt

        s3-router:
          rule: "Host(`s3.nuclide.systems`)"
          service: garage-service
          entrypoints:
            - websecure
          tls:
            certresolver: letsencrypt

      services:
        litellm-service:
          loadBalancer:
            servers:
              - url: "http://192.168.1.40:14000"

        chat-service:
          loadBalancer:
            servers:
              - url: "http://192.168.1.40:14001"

        mcp-service:
          loadBalancer:
            servers:
              - url: "http://192.168.1.40:8080"

        garage-service:
          loadBalancer:
            servers:
              - url: "http://garage:10004"
    EOF

### Step 3: Add Docker Labels to Services

For any Docker service you want to proxy:

    # Example: Add to your service docker-compose.yml
    services:
      ai-service:
        image: your-service
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.your-service.rule=Host(`your-service.nuclide.systems`)"
          - "traefik.http.routers.your-service.entrypoints=websecure"
          - "traefik.http.routers.your-service.tls.certresolver=letsencrypt"
          - "traefik.http.services.your-service.loadBalancer.server.port=8000"

### Step 4: Delete Zoraxy (Optional)

    # Backup Zoraxy configs first
    tar -czf /backup/zoraxy-backup.tar.gz /path/to/zoraxy/configs

    # Stop and remove Zoraxy
    docker rm -f zoraxy || true

## API Example (Traefik)

    # Get list of services
    curl -u traefik:YOUR_TRAEFIK_API_PASSWORD http://localhost:8080/api/http/routers

    # Get Traefik metrics
    curl http://localhost:8080/metrics

    # Reload configuration (live)
    curl -X POST http://localhost:8080/api/http/routers -H "Content-Type: application/json" -d '{...}'

## Migration Checklist

- [ ] Deploy Traefik in host network mode
- [ ] Create Let's Encrypt certificate for your domain
- [ ] Migrate all reverse proxy rules to Traefik labels or dynamic config
- [ ] Test SSL certificates work: `curl -k https://your-domain.nuclide.systems`
- [ ] Remove Zoraxy Docker container
- [ ] Update DNS if needed
- [ ] Verify all endpoints: health checks at new URLs

## Benefits

1. Zero maintenance SSL - Let's Encrypt auto-renews
2. API-driven - No manual Web UI needed
3. Hot reloading - Changes apply immediately
4. Docker-native - Watches container labels automatically
5. Enterprise-grade - Used by major cloud providers