Install
npx skillscat add tachfineamnay/lumirav2/coolify-v4-deployment Install via the SkillsCat registry.
SKILL.md
Coolify v4 Deployment
Context
Lumira V2 is deployed on Coolify v4, a self-hosted PaaS alternative to Vercel/Heroku.
| App | Type | Domain |
|---|---|---|
| Web (SocioPulse) | Next.js | sociopulse.fr |
| Web (MedicoPulse) | Next.js | medicopulse.fr |
| API | NestJS | api.sociopulse.fr |
| PostgreSQL | Database | Internal |
Coolify Architecture
┌─────────────────────────────────────────────────────────┐
│ Coolify Server │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Web App │ │ API App │ │ PostgreSQL │ │
│ │ (Next.js) │ │ (NestJS) │ │ (Database) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ │
│ ┌───────────────────────▼────────────────────────┐ │
│ │ Traefik Reverse Proxy │ │
│ │ (SSL, Load Balancing, Routing) │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘Application Configuration
Web Application (Next.js)
Settings:
| Setting | Value |
|---|---|
| Build Pack | Dockerfile |
| Dockerfile | apps/web/Dockerfile |
| Build Context | / (root) |
| Port | 3000 |
| Health Check | /api/health |
Environment Variables:
NEXT_PUBLIC_API_URL=https://api.sociopulse.fr
NEXT_PUBLIC_BRAND=sociopulse
NEXTAUTH_URL=https://sociopulse.fr
NEXTAUTH_SECRET=your-secret-keyAPI Application (NestJS)
Settings:
| Setting | Value |
|---|---|
| Build Pack | Dockerfile |
| Dockerfile | apps/api/Dockerfile |
| Build Context | / (root) |
| Port | 3001 |
| Health Check | /health |
Environment Variables:
DATABASE_URL=postgresql://user:pass@postgres:5432/lumira
NODE_ENV=production
JWT_SECRET=your-jwt-secret
CORS_ORIGINS=https://sociopulse.fr,https://medicopulse.fr
GOTENBERG_URL=http://gotenberg:3000
VERTEX_AI_PROJECT_ID=your-project-id
VERTEX_AI_CREDENTIALS={"type":"service_account",...}PostgreSQL Database
Settings:
| Setting | Value |
|---|---|
| Type | PostgreSQL |
| Version | 16 |
| Port | 5432 (internal) |
| Volume | Persistent |
Initial Setup:
CREATE DATABASE lumira;
CREATE USER lumira WITH PASSWORD 'your-password';
GRANT ALL PRIVILEGES ON DATABASE lumira TO lumira;Domain Configuration
DNS Setup
# A Records
sociopulse.fr -> Coolify Server IP
medicopulse.fr -> Coolify Server IP
api.sociopulse.fr -> Coolify Server IP
# CNAME (optional)
www.sociopulse.fr -> sociopulse.frSSL Certificates
Coolify automatically provisions Let's Encrypt certificates. Ensure:
- DNS is properly configured
- Port 80/443 are accessible
- Domain is added in Coolify app settings
GitHub Integration
Webhook Setup
- In Coolify: Copy webhook URL from app settings
- In GitHub: Settings → Webhooks → Add webhook
- Payload URL: Coolify webhook URL
- Content type:
application/json - Events:
push(main branch)
Auto-Deploy
Configure in Coolify:
- Branch:
main - Auto-deploy: Enabled
- Build on push: Yes
Database Migrations
Automatic (Recommended)
Add to Dockerfile:
# After build, before CMD
RUN npx prisma migrate deployManual Migration
- SSH into Coolify server
- Access container:
docker exec -it [container_id] sh - Run:
npx prisma migrate deploy
Or via Coolify Terminal:
npx prisma migrate deployRollback Strategies
Quick Rollback
- In Coolify → Deployments
- Find previous successful deployment
- Click "Redeploy"
Git-Based Rollback
git revert HEAD
git push origin main
# Coolify will auto-deploy the revertManual Rollback
- Disable auto-deploy temporarily
- Change branch to specific commit/tag
- Trigger manual deployment
Environment Variables Management
Secrets (Sensitive)
Use Coolify's built-in secrets management:
- Settings → Secrets
- Add secret with name and value
- Reference in app:
${SECRET_NAME}
Environment Groups
Create groups for:
production- All prod variablesstaging- Staging overridesshared- Common across all apps
Logs & Monitoring
View Logs
# In Coolify UI
Applications → [App] → Logs
# Or via SSH
docker logs -f [container_id]Log Persistence
Configure in Coolify:
- Log retention: 7 days
- Log driver: json-file
- Max size: 100MB
Health Checks
API Health Endpoint
// apps/api/src/health/health.controller.ts
@Controller('health')
export class HealthController {
@Get()
check() {
return { status: 'ok', timestamp: new Date().toISOString() };
}
}Coolify Configuration
Health Check:
Path: /health
Interval: 30s
Timeout: 10s
Retries: 3Troubleshooting
| Issue | Solution |
|---|---|
| Build fails | Check Dockerfile path and context |
| Container exits | Check logs for errors |
| Database connection | Verify DATABASE_URL format |
| SSL not working | Check DNS propagation |
| Webhook not triggering | Verify webhook secret |
| Out of memory | Increase container limits |
Common Commands
# Restart app
coolify app:restart [app-id]
# View build logs
coolify app:logs:build [app-id]
# Force rebuild
coolify app:build [app-id] --no-cacheBest Practices
| ✅ DO | ❌ DON'T |
|---|---|
| Use secrets for sensitive data | Hardcode credentials |
| Enable health checks | Skip monitoring setup |
| Set up webhooks | Manually deploy each time |
| Test in staging first | Deploy directly to prod |
| Keep backups of DB | Rely on single instance |
| Monitor disk space | Ignore volume growth |