Fix Coolify deployment: use expose instead of ports

This commit is contained in:
2026-01-02 11:40:35 -06:00
parent 813fafe077
commit 105c5e2198
6 changed files with 703 additions and 4 deletions

339
COOLIFY_DEPLOYMENT.md Normal file
View File

@ -0,0 +1,339 @@
# 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.