Files
erp-nutzfahrzeuge/deploy/coolify-config.md
T

174 lines
5.9 KiB
Markdown

# 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
1. In Coolify, create a new resource
2. Select **Docker Compose** as the resource type
3. Connect your Forgejo/Git repository
4. Set the base directory to the project root
5. Coolify will detect `docker-compose.yml` automatically
### Step 2: Configure Environment Variables
1. Navigate to resource → **Environment Variables**
2. Add all variables from `.env.example` (see `deploy/env.md` for descriptions)
3. **Critical variables:**
- `JWT_SECRET` — generate with `openssl rand -hex 32`
- `POSTGRES_PASSWORD` — strong password for database
- `CORS_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`)
4. **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
5. 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:
1. Ensure persistent storage is enabled for the resource
2. Verify volume names match the compose file
3. For production, consider using a managed PostgreSQL instance instead of the containerized one
### Step 5: Configure Domains / Routing
1. **Backend API:**
- Set domain: `api.your-domain.com` (or subpath)
- Port: `8000`
- This is the primary entry point for Coolify health checks
2. **Frontend:**
- Set domain: `erp.your-domain.com` (or root domain)
- Port: `3000`
- Next.js standalone server
3. **CORS:**
- Set `CORS_ORIGINS` to the frontend domain
- Set `NEXT_PUBLIC_API_URL` to the backend domain
### Step 6: Deploy
1. Click **Deploy** in Coolify
2. Wait for all services to build and start
3. Verify health checks pass (green status for all services)
4. 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/Dockerfile` and `frontend/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'` in `next.config.js`
---
## Post-Deploy Verification
1. All 4 containers are running and healthy
2. `GET /api/v1/health` → 200 `{"status":"ok"}`
3. Frontend loads at production URL
4. Login flow works: `POST /api/v1/auth/login`
5. CORS headers present for frontend origin
6. No errors in container logs
7. File uploads work (test upload to `/data/uploads`)
8. 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:
1. Navigate to resource → **Deployments**
2. Find last known-good deployment
3. Click **Redeploy**
4. Verify health check passes