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
- In Coolify UI, check if you have another deployment using ports 8000 or 5173
- Stop or delete the old deployment
- 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:
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 UI → Your Application → Environment 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:
-
For Backend Service:
- Port:
8000 - Path:
/api(optional, if you want API on subpath)
- Port:
-
For Frontend Service:
- Port:
80 - Path:
/(root path)
- Port:
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>
Recommended: Use the Provided docker-compose.coolify.yml
I've created docker-compose.coolify.yml in your project. To use it:
-
In Coolify UI:
- Go to your application settings
- Under "Docker Compose File", specify:
docker-compose.coolify.yml
-
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 -
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?
- Check Coolify logs for the exact container that's conflicting
- Stop all related deployments in Coolify
- Prune Docker on server:
docker system prune -af - Redeploy
Database Issues?
Coolify creates persistent volumes automatically. To reset:
- In Coolify UI → Your App → Storages
- Delete the
sqlite_datavolume - Redeploy
Build Failures?
- Check that
email-validator==2.1.1is inbackend/requirements.txt - Ensure frontend has
npm run buildscript inpackage.json - Check Coolify build logs for specific errors
Next Steps
- ✅ Update docker-compose.yml to use
exposeinstead ofports - ✅ Create production Dockerfile for frontend
- ✅ Set environment variables in Coolify UI
- ✅ Configure routing in Coolify
- ✅ Deploy and test!
Need more help? Check the Coolify documentation or share the full deployment logs.