5.9 KiB
5.9 KiB
Coolify Deployment Configuration — ERP Nutzfahrzeuge
Overview
This document describes how to deploy the ERP Nutzfahrzeuge system on Coolify using Docker Compose.
The system consists of 4 services:
| Service | Image | Port | Health Check |
|---|---|---|---|
| Backend | Custom (Python 3.13-slim) | 8000 | GET /api/v1/health |
| Frontend | Custom (Node 18-alpine) | 3000 | GET / |
| PostgreSQL | postgres:16-alpine |
5432 | pg_isready |
| Redis | redis:7-alpine |
6379 | redis-cli ping |
Coolify Resource Setup
Step 1: Create Resource
- In Coolify, create a new resource
- Select Docker Compose as the resource type
- Connect your Forgejo/Git repository
- Set the base directory to the project root
- Coolify will detect
docker-compose.ymlautomatically
Step 2: Configure Environment Variables
- Navigate to resource → Environment Variables
- Add all variables from
.env.example(seedeploy/env.mdfor descriptions) - Critical variables:
JWT_SECRET— generate withopenssl rand -hex 32POSTGRES_PASSWORD— strong password for databaseCORS_ORIGINS— production frontend URL (e.g.,https://erp.your-domain.com)NEXT_PUBLIC_API_URL— production backend URL (e.g.,https://api.your-domain.com/api/v1)
- Optional but feature-dependent:
OPENROUTER_API_KEY— required for AI features (OCR, retouch, copilot)MOBILE_DE_API_KEY+MOBILE_DE_SELLER_ID— required for mobile.de integration
- Click Save and redeploy
Step 3: Configure Health Check
In the resource settings:
| Setting | Value |
|---|---|
| Health check path | /api/v1/health |
| Health check port | 8000 |
| Health check interval | 30s |
| Health check timeout | 5s |
| Health check retries | 3 |
Note: The health check targets the backend service. Docker Compose health checks are also defined per-service in
docker-compose.yml.
Step 4: Configure Persistent Storage
Docker Compose volumes are defined in docker-compose.yml:
| Volume | Mount Point | Purpose |
|---|---|---|
uploads |
/data/uploads (backend) |
User file uploads (images, documents) |
pgdata |
/var/lib/postgresql/data (postgres) |
Database data |
redisdata |
/data (redis) |
Redis persistence (AOF) |
In Coolify:
- Ensure persistent storage is enabled for the resource
- Verify volume names match the compose file
- For production, consider using a managed PostgreSQL instance instead of the containerized one
Step 5: Configure Domains / Routing
-
Backend API:
- Set domain:
api.your-domain.com(or subpath) - Port:
8000 - This is the primary entry point for Coolify health checks
- Set domain:
-
Frontend:
- Set domain:
erp.your-domain.com(or root domain) - Port:
3000 - Next.js standalone server
- Set domain:
-
CORS:
- Set
CORS_ORIGINSto the frontend domain - Set
NEXT_PUBLIC_API_URLto the backend domain
- Set
Step 6: Deploy
- Click Deploy in Coolify
- Wait for all services to build and start
- Verify health checks pass (green status for all services)
- Test endpoints:
GET https://api.your-domain.com/api/v1/health→ 200{"status":"ok"}GET https://erp.your-domain.com/→ 200 (frontend loads)GET https://api.your-domain.com/openapi.json→ 200 (API schema)
Coolify Service Type
- Type: Docker Compose (multi-service)
- Compose file:
docker-compose.yml(project root) - Build: Coolify builds images from
backend/Dockerfileandfrontend/Dockerfile - Pre-built images:
postgres:16-alpine,redis:7-alpine
Port Mapping
| Service | Internal Port | External Port | Notes |
|---|---|---|---|
| Backend | 8000 | 8000 | FastAPI + uvicorn (4 workers) |
| Frontend | 3000 | 3000 | Next.js standalone server |
| PostgreSQL | 5432 | — (internal only) | Not exposed externally |
| Redis | 6379 | — (internal only) | Not exposed externally |
In Coolify, only expose backend (8000) and frontend (3000) via domains. PostgreSQL and Redis should remain internal to the Docker network.
Build Configuration
Backend
- Base image:
python:3.13-slim - System packages: libpango, libcairo, libjpeg, libpng (for WeasyPrint + Pillow)
- Python venv:
/opt/venv - Entry:
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
Frontend
- Base image:
node:18-alpine(multi-stage) - Build:
npm ci && npm run build(standalone output) - Entry:
node server.js - Requires:
output: 'standalone'innext.config.js
Post-Deploy Verification
- All 4 containers are running and healthy
GET /api/v1/health→ 200{"status":"ok"}- Frontend loads at production URL
- Login flow works:
POST /api/v1/auth/login - CORS headers present for frontend origin
- No errors in container logs
- File uploads work (test upload to
/data/uploads) - Database queries return expected data
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Backend health check fails | DB not ready | Check postgres container health; increase start_period |
| WeasyPrint errors | Missing system libs | Verify libpango, libcairo installed in backend image |
| Frontend build fails | Missing output: 'standalone' |
Add output: 'standalone' to next.config.js |
| CORS errors | Wrong CORS_ORIGINS |
Set to exact frontend domain (no trailing slash) |
| AI features fail | Missing OPENROUTER_API_KEY |
Set API key in Coolify environment variables |
| mobile.de fails | Missing credentials | Set MOBILE_DE_API_KEY and MOBILE_DE_SELLER_ID |
Rollback
See deploy/rollback.md for the full rollback procedure.
Quick rollback in Coolify:
- Navigate to resource → Deployments
- Find last known-good deployment
- Click Redeploy
- Verify health check passes