Files
h2h-prototype/COOLIFY_DEPLOYMENT.md

7.6 KiB

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

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:

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:

# 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:

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 UIYour ApplicationEnvironment Variables, add:

# 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:

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

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:

# 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:

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

# 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>

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:

    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:

# 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:
    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.