# Coolify Deployment Guide

## Issue: Port Already Allocated

**Error you're seeing:**
```
Bind for 0.0.0.0:8000 failed: port is already allocated
```

**Root Cause:**
Your current `docker-compose.yml` has explicit port bindings (`ports: - "8000:8000"`), which conflicts with Coolify's routing system or other services on the server.

## Solution: Two Options

### Option 1: Quick Fix - Stop Conflicting Services

1. **In Coolify UI**, check if you have another deployment using ports 8000 or 5173
2. Stop or delete the old deployment
3. Retry your current deployment

### Option 2: Use Coolify-Compatible Configuration (Recommended)

Coolify uses Traefik reverse proxy to route traffic. You don't need explicit port mappings.

## Steps to Fix

### 1. Update Your docker-compose.yml for Coolify

Replace your `docker-compose.yml` with this Coolify-compatible version:

```yaml
services:
  backend:
    build: ./backend
    restart: unless-stopped
    environment:
      - DATABASE_URL=sqlite+aiosqlite:///./data/h2h.db
      - JWT_SECRET=${JWT_SECRET}
      - JWT_ALGORITHM=HS256
      - ACCESS_TOKEN_EXPIRE_MINUTES=30
      - REFRESH_TOKEN_EXPIRE_DAYS=7
    volumes:
      - sqlite_data:/app/data
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000
    # Use 'expose' instead of 'ports' for Coolify
    expose:
      - "8000"

  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.prod
    restart: unless-stopped
    environment:
      - VITE_API_URL=${VITE_API_URL:-https://your-domain.com/api}
      - VITE_WS_URL=${VITE_WS_URL:-wss://your-domain.com}
    depends_on:
      - backend
    # Use 'expose' instead of 'ports' for Coolify
    expose:
      - "80"

volumes:
  sqlite_data:
```

**Key Changes:**
- ❌ Removed `ports:` (which binds to host)
- ✅ Added `expose:` (internal container communication only)
- ✅ Added `restart: unless-stopped`
- ✅ Frontend uses production build

### 2. Create Production Dockerfile for Frontend

Create `frontend/Dockerfile.prod`:

```dockerfile
# Build stage
FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Production stage
FROM nginx:alpine

# Copy built assets from builder
COPY --from=builder /app/dist /usr/share/nginx/html

# Copy nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
```

### 3. Create Nginx Config for Frontend

Create `frontend/nginx.conf`:

```nginx
server {
    listen 80;
    server_name _;
    root /usr/share/nginx/html;
    index index.html;

    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # API proxy to backend
    location /api/ {
        proxy_pass http://backend:8000/api/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    # WebSocket proxy
    location /ws {
        proxy_pass http://backend:8000/ws;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }

    # Serve static files
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Cache static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
```

### 4. Configure Coolify Environment Variables

In **Coolify UI** → **Your Application** → **Environment Variables**, add:

```bash
# JWT Secret (generate a secure random string)
JWT_SECRET=your-very-secure-random-secret-key-min-32-chars-change-this

# API URL for frontend (use your Coolify domain)
VITE_API_URL=https://your-app.yourdomain.com/api

# WebSocket URL (use your Coolify domain)
VITE_WS_URL=wss://your-app.yourdomain.com
```

### 5. Configure Coolify Routing

In **Coolify UI**:

1. **For Backend Service:**
   - Port: `8000`
   - Path: `/api` (optional, if you want API on subpath)

2. **For Frontend Service:**
   - Port: `80`
   - Path: `/` (root path)

## Alternative: Simpler Single-Container Approach

If the multi-service setup is complex, you can deploy backend and frontend separately:

### Backend-Only Deployment

Use original backend with ports exposed:

```yaml
services:
  backend:
    build: ./backend
    ports:
      - "8000:8000"  # Coolify can handle this if no conflicts
    environment:
      - DATABASE_URL=sqlite+aiosqlite:///./data/h2h.db
      - JWT_SECRET=${JWT_SECRET}
    volumes:
      - sqlite_data:/app/data
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000

volumes:
  sqlite_data:
```

**In Coolify:**
- Set public port to 8000
- Domain: `api.yourdomain.com`

### Frontend-Only Deployment

```yaml
services:
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.prod
    ports:
      - "80:80"
    environment:
      - VITE_API_URL=https://api.yourdomain.com/api
      - VITE_WS_URL=wss://api.yourdomain.com
```

**In Coolify:**
- Set public port to 80
- Domain: `app.yourdomain.com`

## Quick Fixes for Current Error

### Fix 1: Remove Port Bindings

In your `docker-compose.yml`, change:

```yaml
# FROM:
ports:
  - "8000:8000"

# TO:
expose:
  - "8000"
```

Do this for both backend and frontend.

### Fix 2: Use Different Ports

If you must use port bindings, use different ports:

```yaml
services:
  backend:
    ports:
      - "8001:8000"  # Changed to 8001

  frontend:
    ports:
      - "5174:5173"  # Changed to 5174
```

Then configure these ports in Coolify UI.

### Fix 3: Check Coolify for Running Services

```bash
# SSH into your Coolify server
ssh your-server

# Check what's using port 8000
sudo lsof -i :8000

# Stop the service if needed
sudo docker stop <container-id>
```

## Recommended: Use the Provided docker-compose.coolify.yml

I've created `docker-compose.coolify.yml` in your project. To use it:

1. **In Coolify UI:**
   - Go to your application settings
   - Under "Docker Compose File", specify: `docker-compose.coolify.yml`

2. **Or rename it:**
   ```bash
   mv docker-compose.yml docker-compose.local.yml  # Backup local version
   mv docker-compose.coolify.yml docker-compose.yml
   git add .
   git commit -m "Configure for Coolify deployment"
   git push
   ```

3. **Redeploy in Coolify**

## Testing After Deployment

Once deployed, test:

```bash
# Test backend
curl https://your-app.yourdomain.com/api/v1/health

# Or visit in browser
https://your-app.yourdomain.com/docs  # API documentation
https://your-app.yourdomain.com       # Frontend
```

## Troubleshooting

### Still Getting Port Errors?

1. **Check Coolify logs** for the exact container that's conflicting
2. **Stop all related deployments** in Coolify
3. **Prune Docker on server:**
   ```bash
   docker system prune -af
   ```
4. **Redeploy**

### Database Issues?

Coolify creates persistent volumes automatically. To reset:

1. In Coolify UI → Your App → Storages
2. Delete the `sqlite_data` volume
3. Redeploy

### Build Failures?

- Check that `email-validator==2.1.1` is in `backend/requirements.txt`
- Ensure frontend has `npm run build` script in `package.json`
- Check Coolify build logs for specific errors

## Next Steps

1. ✅ Update docker-compose.yml to use `expose` instead of `ports`
2. ✅ Create production Dockerfile for frontend
3. ✅ Set environment variables in Coolify UI
4. ✅ Configure routing in Coolify
5. ✅ Deploy and test!

---

**Need more help?** Check the Coolify documentation or share the full deployment logs.
