Files
leocrm/DEPLOY.md
T
Agent Zero 5b7d93cd0e refactor(deploy): remove old multi-resource code, document single docker-compose workflow
- Remove POSTGRES_COMPOSE, REDIS_COMPOSE templates (unused)
- Remove create_service(), create_api_application(), generate_worker_compose()
- Remove deploy_worker(), deploy_worker_only(), verify_worker_service()
- Remove resolve_worker_uuid() and all worker_uuid references
- Remove get_worker_envs(), get_api_envs(), get_postgres_envs(), get_redis_envs()
- Remove set_service_envs(), set_application_envs() (dead code)
- Remove _extract_deploy_uuid(), _wait_service_healthy() (only used by deploy_worker)
- Remove seed_admin_user() (only used by old deploy_full)
- Remove DB_HOST, REDIS_HOST, WORKER_UUID, WORKER_NAME config vars
- Remove --worker-only CLI arg
- Replace old deploy_full() with simple redeploy via /api/v1/deploy
- Update run_verification() to remove worker_uuid param
- Add KI workflow comment at top of deploy.py
- Update DEPLOY.md: single docker-compose stack workflow
- Update COOLIFY_SETUP.md: single docker-compose stack, remove 3-resource setup
- Update docs/INSTALL.md: automated --initial workflow

deploy.py: 1370 → 893 lines (-477 lines, -35%)
2026-08-06 01:22:09 +02:00

6.8 KiB

LeoCRM Deployment

Architektur

LeoCRM läuft als einzelner docker-compose Stack in Coolify. Alle 4 Container (PostgreSQL, Redis, API, Worker) werden aus der docker-compose.yaml im Git-Repo gestartet und teilen sich ein Docker-Netzwerk.

┌─────────────────────────────────────────────┐
│         Coolify Application (docker-compose) │
│  ┌──────────┐  ┌──────────┐                 │
│  │ postgres │  │  redis   │                 │
│  └────┬─────┘  └────┬─────┘                 │
│       │              │                       │
│  ┌────┴─────┐  ┌────┴─────┐                 │
│  │ crm_app  │  │crm_worker│                 │
│  │ (API)    │  │ (ARQ)    │                 │
│  └──────────┘  └──────────┘                 │
└─────────────────────────────────────────────┘

Keine separaten Coolify Services für DB/Redis/Worker. Alles in einem Stack.

Quick Start

Redeploy (bestehende Anwendung)

# Umgebungsvariablen setzen
export COOLIFY_API_TOKEN="dein-token"
export APP_DOMAIN="https://crm.media-on.de"
export COOLIFY_APP_UUID="dx4pqdziu4uj6x9fxs1u5z0x"  # optional, wird via APP_NAME gesucht

# Redeploy via Coolify API
python scripts/deploy.py

# Verifikation nur
python scripts/deploy.py --verify-only

Das Script macht automatisch:

  1. Coolify Application auflösen (via UUID oder Name)
  2. Deploy via /api/v1/deploy triggern
  3. Auf Deployment-Erfolg warten
  4. HTTP Health-Check verifizieren
  5. Login-Test (optional, wenn LOGIN_EMAIL/LOGIN_PASSWORD gesetzt)
  6. Alembic-Migration-Head prüfen (via SSH)
  7. RLS-Tabellen zählen (via SSH)

Initial Deployment (neue Anwendung)

# Alle Umgebungsvariablen setzen
export COOLIFY_API_TOKEN="dein-token"
export APP_DOMAIN="https://crm.media-on.de"
export APP_NAME="leocrm"  # Coolify Application Name
export DB_PASSWORD="..."
export REDIS_PASSWORD="..."
export SECRET_KEY="..."
export COOLIFY_PROJECT_UUID="..."
export COOLIFY_SERVER_UUID="..."
export COOLIFY_PRIVATE_KEY_UUID="..."
export COOLIFY_ENVIRONMENT="production"  # optional, default: production

# Initial deployment
python scripts/deploy.py --initial

Das Script macht automatisch:

  1. Coolify Application via private-deploy-key erstellen
  2. Build Pack auf dockercompose setzen (liest docker-compose.yaml aus Git)
  3. Environment-Variablen setzen (Secrets, Domain, Admin-Credentials)
  4. Erster Deploy (ohne Domain — Coolify muss docker-compose.yaml lesen)
  5. docker_compose_domains setzen + Redeploy (mit Traefik-Labels)
  6. Verifikation (HTTP, Login, Alembic, RLS)

Option B: Docker Compose (lokal / ohne Coolify)

# .env.docker erstellen
cp .env.docker.example .env.docker
$EDITOR .env.docker  # SECRET_KEY, DB_PASSWORD, REDIS_PASSWORD etc. ausfüllen

# Starten (alle 4 Container: Postgres, Redis, App, Worker)
docker compose --env-file .env.docker up --build -d

# Health check
curl http://localhost:8000/api/v1/health

# Stoppen
docker compose down

Container:

  • postgres — PostgreSQL 16 mit pgvector
  • redis — Redis 7
  • crm_app — FastAPI API Server
  • crm_worker — ARQ Background Worker

Alle mit persistenten Volumes. Kein Datenverlust bei Redeploy.

Voraussetzungen

  • Python 3.12+
  • httpx Python package
  • Docker & Docker Compose (für Option B)
  • Coolify v4+ (für Option A)
  • SSH-Zugang zum Server (für Verifikation, Option A)

Umgebungsvariablen

Siehe .env.example für alle Variablen. Wichtigste:

Variable Pflicht Default Beschreibung
COOLIFY_API_TOKEN Ja Coolify API Token
APP_DOMAIN Ja App-Domain (z.B. https://crm.media-on.de)
COOLIFY_APP_UUID Nein Application UUID (auto-resolved via APP_NAME)
APP_NAME Nein abgeleitet aus APP_DOMAIN Coolify Application Name
SSH_KEY Nein /a0/usr/workdir/.ssh/coolify-01-root SSH Key für Verifikation
SERVER_IP Nein 46.225.91.159 Server IP für SSH
LOGIN_EMAIL Nein Login-Test Email (optional)
LOGIN_PASSWORD Nein Login-Test Passwort (optional)

Nur für --initial:

Variable Pflicht Beschreibung
DB_PASSWORD Ja PostgreSQL Passwort
REDIS_PASSWORD Ja Redis Passwort
SECRET_KEY Ja Application Secret Key (min. 32 Zeichen)
COOLIFY_PROJECT_UUID Ja Coolify Project UUID
COOLIFY_SERVER_UUID Ja Coolify Server UUID
COOLIFY_PRIVATE_KEY_UUID Ja Coolify Private Deploy Key UUID
COOLIFY_ENVIRONMENT Nein Coolify Environment (default: production)

S3 Storage (optional)

Die App unterstützt S3-kompatiblen Storage. Setze:

STORAGE_BACKEND=s3
S3_ENDPOINT=https://s3.example.com
S3_BUCKET=leocrm
S3_ACCESS_KEY=...
S3_SECRET_KEY=...

Mehrere Instanzen

Mehrere LeoCRM-Instanzen auf demselben Coolify-Server:

# Test-Instanz
APP_NAME=leocrm-test APP_DOMAIN=https://crm-test.media-on.de python scripts/deploy.py --initial

# Produktions-Instanz
APP_NAME=leocrm APP_DOMAIN=https://crm.media-on.de python scripts/deploy.py --initial

Jede Instanz hat eigene DB, Redis, Container und Domain.

Troubleshooting

Container nicht healthy:

docker logs <container-name> --tail 50

Migration fehlgeschlagen:

docker exec <container> alembic upgrade head

503 Fehler (Traefik):

  • Domain ohne :443 in docker_compose_domains setzen
  • Service-Namen mit Unterstrichen in docker-compose.yaml (crm_app, nicht crm-app)
  • docker-compose.yaml (nicht .yml) als Dateiname

Backup & Restore

Backup (PostgreSQL)

# Full DB backup (run on the host or via docker exec)
docker exec <postgres-container> pg_dump -U crm_user -Fc crm_db > backup_$(date +%Y%m%d_%H%M%S).dump

Backup (Redis — Sessions/Queues)

docker exec <redis-container> redis-cli -a "$REDIS_PASSWORD" SAVE
docker cp <redis-container>:/data/dump.rdb redis_backup_$(date +%Y%m%d).rdb

Restore (PostgreSQL)

# Stop app containers
docker compose stop crm_app crm_worker

# Restore DB
docker exec -i <postgres-container> pg_restore -U crm_user -d crm_db --clean < backup_20260726.dump

# Restart app
docker compose start crm_app crm_worker

Automatisierte Backups (Cron)

# /etc/cron.d/leocrm-backup
0 2 * * * root docker exec <postgres-container> pg_dump -U crm_user -Fc crm_db > /backups/leocrm_$(date +\%Y\%m\%d).dump
0 3 * * * root find /backups -name 'leocrm_*.dump' -mtime +30 -delete

Empfehlung: Tägliche DB-Backups, 30 Tage Aufbewahrung. Storage-Backup wöchentlich.