mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 01:01:09 +02:00
docs: remove all Coolify references from codebase
Replace Coolify with Docker Compose throughout documentation. The project never used Coolify - a removal script was created but never executed, leaving incorrect documentation. Changes: - Delete 13 heavily Coolify-focused docs files - Update ~30 files replacing Coolify → Docker Compose - Remove obsolete removal script - Fix deployment references in active and archived projects 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
79b4bb07ed
commit
c61dcb8ff9
42 changed files with 176 additions and 4741 deletions
|
|
@ -80,7 +80,7 @@ The manacore-monorepo uses a comprehensive CI/CD pipeline with the following fea
|
|||
- **Docker Hub**: For image storage (or alternative registry)
|
||||
- **Supabase**: For database services
|
||||
- **Azure**: For OpenAI services
|
||||
- **Hetzner/Coolify**: For hosting (recommended)
|
||||
- **Hetzner + Docker Compose**: For hosting (recommended)
|
||||
|
||||
### GitHub Secrets
|
||||
|
||||
|
|
|
|||
|
|
@ -745,20 +745,20 @@ pnpm docker:down
|
|||
|
||||
---
|
||||
|
||||
### 2. Production Orchestration (Coolify)
|
||||
### 2. Production Orchestration (Docker Compose)
|
||||
|
||||
**Coolify Configuration:** `.coolify/docker-compose.prod.yml`
|
||||
**Production Configuration:** `docker-compose.production.yml`
|
||||
|
||||
```yaml
|
||||
version: '3.9'
|
||||
|
||||
# Production Docker Compose for Coolify Deployment
|
||||
# Coolify will handle:
|
||||
# - Automatic SSL (Let's Encrypt)
|
||||
# Production Docker Compose Deployment
|
||||
# With:
|
||||
# - Automatic SSL (Certbot/Let's Encrypt)
|
||||
# - Health check monitoring
|
||||
# - Auto-restart on failure
|
||||
# - Log aggregation
|
||||
# - Resource limits
|
||||
# - Nginx reverse proxy
|
||||
|
||||
services:
|
||||
chat-backend:
|
||||
|
|
@ -785,19 +785,18 @@ services:
|
|||
retries: 3
|
||||
start_period: 40s
|
||||
labels:
|
||||
- "coolify.managed=true"
|
||||
- "coolify.project=chat"
|
||||
- "coolify.service=backend"
|
||||
- "coolify.port=3002"
|
||||
- "coolify.domain=api-chat.manacore.app"
|
||||
- "com.manacore.project=chat"
|
||||
- "com.manacore.service=backend"
|
||||
- "com.manacore.port=3002"
|
||||
- "com.manacore.domain=api-chat.manacore.app"
|
||||
```
|
||||
|
||||
**Coolify Deployment Strategy:**
|
||||
**Docker Compose Deployment Strategy:**
|
||||
|
||||
1. **Per-project services**: Each project (chat, maerchenzauber, etc.) deployed as separate Coolify application
|
||||
2. **Resource pools**: Shared PostgreSQL and Redis as Coolify resources
|
||||
3. **Auto-scaling**: Configure horizontal scaling based on CPU/memory
|
||||
4. **Blue-green deployments**: Coolify's native zero-downtime deployment
|
||||
1. **Per-project services**: Each project (chat, picture, etc.) deployed as separate service stack
|
||||
2. **Shared infrastructure**: PostgreSQL and Redis in dedicated compose file
|
||||
3. **Manual scaling**: Scale with `docker compose up --scale service=N`
|
||||
4. **Blue-green deployments**: Scripted zero-downtime deployment via Nginx
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -967,7 +966,7 @@ k8s/
|
|||
│ │
|
||||
│ [Development] → [Staging] → [Production] │
|
||||
│ ↓ ↓ ↓ │
|
||||
│ Local Docker Coolify Coolify/K8s │
|
||||
│ Local Docker Docker Docker/K8s │
|
||||
│ 127.0.0.1 staging.* app domains │
|
||||
│ Hot reload Manual test Blue-green │
|
||||
│ No SSL Let's Encrypt Let's Encrypt │
|
||||
|
|
@ -1042,7 +1041,7 @@ k8s/
|
|||
│ BLUE-GREEN DEPLOYMENT │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ [Load Balancer / Coolify Proxy] │
|
||||
│ [Load Balancer / Nginx Proxy] │
|
||||
│ ↓ │
|
||||
│ ┌──────────────────┐ ┌──────────────────┐ │
|
||||
│ │ BLUE (Live) │ │ GREEN (Standby) │ │
|
||||
|
|
@ -1066,7 +1065,7 @@ k8s/
|
|||
|
||||
```bash
|
||||
# Instant rollback by switching traffic back to BLUE
|
||||
coolify switch-deployment blue
|
||||
./scripts/switch-deployment.sh blue
|
||||
|
||||
# Or with Kubernetes
|
||||
kubectl set image deployment/chat-backend chat-backend=registry.manacore.app/chat-backend:v1.5.2
|
||||
|
|
@ -1246,8 +1245,8 @@ Development → Staging → Production
|
|||
# Manual trigger (after staging validation)
|
||||
kubectl exec -it chat-backend-pod -- pnpm migration:run
|
||||
|
||||
# Or automated (Coolify)
|
||||
coolify deploy chat-backend --run-migrations
|
||||
# Or automated (via deploy script)
|
||||
./scripts/deploy/deploy-hetzner.sh chat-backend --run-migrations
|
||||
```
|
||||
|
||||
**Migration Safety Rules:**
|
||||
|
|
@ -1419,7 +1418,7 @@ async updateCredits(userId: string, amount: number) {
|
|||
│ - https://docs.manacore.app → API documentation │
|
||||
│ │
|
||||
│ All domains: │
|
||||
│ - SSL via Let's Encrypt (Coolify auto-provision) │
|
||||
│ - SSL via Let's Encrypt (Certbot auto-provision) │
|
||||
│ - HTTP/2 enabled │
|
||||
│ - HSTS headers (max-age=31536000) │
|
||||
│ - Cloudflare DNS (with proxy for DDoS protection) │
|
||||
|
|
@ -1432,7 +1431,7 @@ async updateCredits(userId: string, amount: number) {
|
|||
```
|
||||
Type Name Target Proxy
|
||||
─────────────────────────────────────────────────────────────────────
|
||||
A chat.manacore.app 185.230.123.45 (Coolify IP) Yes
|
||||
A chat.manacore.app 185.230.123.45 (Server IP) Yes
|
||||
A app-chat.manacore.app 185.230.123.45 Yes
|
||||
A api-chat.manacore.app 185.230.123.45 No*
|
||||
CNAME *.manacore.app manacore.app Yes
|
||||
|
|
@ -1444,16 +1443,14 @@ CNAME *.manacore.app manacore.app Yes
|
|||
|
||||
### 2. SSL/TLS Certificate Management
|
||||
|
||||
**Coolify Automatic SSL:**
|
||||
**Automatic SSL (Certbot):**
|
||||
|
||||
```yaml
|
||||
# .coolify/settings.yml
|
||||
ssl:
|
||||
provider: letsencrypt
|
||||
email: devops@manacore.app
|
||||
staging: false # Use production Let's Encrypt
|
||||
auto_renew: true
|
||||
renewal_days_before: 30
|
||||
```bash
|
||||
# Install certbot
|
||||
apt-get install certbot python3-certbot-nginx
|
||||
|
||||
# Configure auto-renewal
|
||||
systemctl enable certbot.timer
|
||||
```
|
||||
|
||||
**Manual SSL (Certbot):**
|
||||
|
|
@ -1513,7 +1510,7 @@ server {
|
|||
- **Simplicity**: Each backend has its own domain
|
||||
- **Low traffic volume**: Gateway overhead not justified yet
|
||||
- **Independent scaling**: Services scale independently
|
||||
- **Coolify routing**: Built-in reverse proxy handles routing
|
||||
- **Nginx routing**: Reverse proxy handles routing
|
||||
|
||||
**Future API Gateway (Kong/Traefik) - When to Adopt:**
|
||||
|
||||
|
|
@ -1704,13 +1701,13 @@ location ~* \.(html)$ {
|
|||
**Secret Management:**
|
||||
|
||||
- **Development:** `.env.development` (committed to git)
|
||||
- **Staging/Production:** Coolify secrets UI or Kubernetes secrets
|
||||
- **Staging/Production:** Environment files or Kubernetes secrets
|
||||
|
||||
```bash
|
||||
# Coolify secret injection
|
||||
coolify env set chat-backend \
|
||||
AZURE_OPENAI_API_KEY=secret123 \
|
||||
DATABASE_URL=postgresql://...
|
||||
# Docker Compose secret injection via .env files
|
||||
# /opt/manacore/.env.production
|
||||
AZURE_OPENAI_API_KEY=secret123
|
||||
DATABASE_URL=postgresql://...
|
||||
```
|
||||
|
||||
**Kubernetes Secrets:**
|
||||
|
|
@ -2163,14 +2160,14 @@ jobs:
|
|||
url: https://staging-chat.manacore.app
|
||||
|
||||
steps:
|
||||
- name: Deploy to Coolify (Staging)
|
||||
- name: Deploy to Staging
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.COOLIFY_STAGING_HOST }}
|
||||
username: ${{ secrets.COOLIFY_SSH_USER }}
|
||||
key: ${{ secrets.COOLIFY_SSH_KEY }}
|
||||
host: ${{ secrets.STAGING_HOST }}
|
||||
username: ${{ secrets.STAGING_SSH_USER }}
|
||||
key: ${{ secrets.STAGING_SSH_KEY }}
|
||||
script: |
|
||||
cd /var/lib/coolify/apps/chat-staging
|
||||
cd /opt/manacore/chat-staging
|
||||
docker compose pull
|
||||
docker compose up -d --force-recreate
|
||||
docker compose exec -T chat-backend pnpm migration:run
|
||||
|
|
@ -2192,14 +2189,14 @@ jobs:
|
|||
url: https://chat.manacore.app
|
||||
|
||||
steps:
|
||||
- name: Deploy to Coolify (Production)
|
||||
- name: Deploy to Production
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.COOLIFY_PROD_HOST }}
|
||||
username: ${{ secrets.COOLIFY_SSH_USER }}
|
||||
key: ${{ secrets.COOLIFY_SSH_KEY }}
|
||||
host: ${{ secrets.PRODUCTION_HOST }}
|
||||
username: ${{ secrets.PRODUCTION_SSH_USER }}
|
||||
key: ${{ secrets.PRODUCTION_SSH_KEY }}
|
||||
script: |
|
||||
cd /var/lib/coolify/apps/chat-production
|
||||
cd /opt/manacore/chat-production
|
||||
|
||||
# Blue-green deployment: Deploy to green environment
|
||||
docker compose -f docker-compose.green.yml pull
|
||||
|
|
@ -2214,8 +2211,8 @@ jobs:
|
|||
# Health check green environment
|
||||
curl -f http://localhost:3002/api/health || exit 1
|
||||
|
||||
# Switch traffic to green (update Coolify routing)
|
||||
coolify switch-deployment chat green
|
||||
# Switch traffic to green (update Nginx routing)
|
||||
./scripts/switch-deployment.sh chat green
|
||||
|
||||
# Keep blue running for 1 hour (rollback window)
|
||||
# Decommission blue after validation
|
||||
|
|
@ -2356,8 +2353,9 @@ curl -f https://api-chat.manacore.app/api/health
|
|||
|
||||
```bash
|
||||
# 1. Provision new server (same specs)
|
||||
# 2. Install Docker + Coolify
|
||||
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
|
||||
# 2. Install Docker + Docker Compose
|
||||
curl -fsSL https://get.docker.com | bash
|
||||
apt-get update && apt-get install -y docker-compose-plugin
|
||||
|
||||
# 3. Clone repository
|
||||
git clone https://github.com/manacore/manacore-monorepo.git
|
||||
|
|
@ -2577,7 +2575,7 @@ services:
|
|||
|
||||
### 3. Secrets Management
|
||||
|
||||
**Current:** Coolify environment variables UI (encrypted at rest)
|
||||
**Current:** Docker Compose environment files (encrypted at rest)
|
||||
|
||||
**Future:** HashiCorp Vault or AWS Secrets Manager
|
||||
|
||||
|
|
@ -2691,7 +2689,7 @@ Permissions-Policy: geolocation=(), microphone=(), camera=()
|
|||
- [ ] Set up GitHub Actions workflows (per project)
|
||||
- [ ] Configure Docker image registry (GitHub Container Registry)
|
||||
- [ ] Implement automated testing in CI
|
||||
- [ ] Set up staging environment on Coolify
|
||||
- [ ] Set up staging environment with Docker Compose
|
||||
- [ ] Implement blue-green deployment scripts
|
||||
|
||||
### Phase 3: Production Deployment (Week 5-6)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
│ (Nginx/Static) │
|
||||
▼ ▼
|
||||
┌──────────────────┐ ┌──────────────────┐
|
||||
│ Landing Servers │ │ Coolify/K8s LB │
|
||||
│ Landing Servers │ │ Docker/K8s LB │
|
||||
│ - chat.app │ │ (Load Balancer) │
|
||||
│ - picture.app │ └────────┬─────────┘
|
||||
│ - memoro.app │ │
|
||||
|
|
@ -181,7 +181,7 @@ TOTAL BUILD TIME:
|
|||
│
|
||||
▼
|
||||
┌─────────────────────────────────┐
|
||||
│ Cloudflare / Coolify Proxy │
|
||||
│ Cloudflare / Nginx Proxy │
|
||||
│ - DDoS Protection │
|
||||
│ - SSL Termination │
|
||||
│ - Rate Limiting │
|
||||
|
|
@ -237,7 +237,7 @@ NETWORK SECURITY RULES:
|
|||
|
||||
SSL/TLS CONFIGURATION:
|
||||
|
||||
Certificate Provider: Let's Encrypt (Coolify auto-provision)
|
||||
Certificate Provider: Let's Encrypt (Certbot auto-provision)
|
||||
Protocols: TLSv1.2, TLSv1.3
|
||||
Cipher Suites: HIGH:!aNULL:!MD5:!3DES
|
||||
HSTS: max-age=31536000; includeSubDomains; preload
|
||||
|
|
@ -270,7 +270,7 @@ SSL/TLS CONFIGURATION:
|
|||
│
|
||||
▼
|
||||
┌───────────────────────────┐
|
||||
│ Coolify Reverse Proxy │
|
||||
│ Nginx Reverse Proxy │
|
||||
│ - SSL termination │
|
||||
│ - Route to container │
|
||||
│ - Health check │
|
||||
|
|
@ -400,7 +400,7 @@ CACHING STRATEGY:
|
|||
```
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ CI/CD DEPLOYMENT PIPELINE │
|
||||
│ (GitHub Actions → Coolify) │
|
||||
│ (GitHub Actions → Docker Compose) │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
[Developer]
|
||||
|
|
@ -464,7 +464,7 @@ CACHING STRATEGY:
|
|||
┌───────────────────────────┐
|
||||
│ Deploy to Staging │
|
||||
│ ┌─────────────────────┐ │
|
||||
│ │ SSH to Coolify │ │
|
||||
│ │ SSH to server │ │
|
||||
│ │ docker compose pull │ │
|
||||
│ │ docker compose up │ │
|
||||
│ │ pnpm migration:run │ │
|
||||
|
|
@ -604,7 +604,7 @@ DEPLOYMENT TIMELINE:
|
|||
|
||||
ROLLBACK PROCEDURE (if needed):
|
||||
1. Detect issue (error spike, customer reports)
|
||||
2. Run: coolify switch-deployment chat blue
|
||||
2. Run: ./scripts/switch-deployment.sh chat blue
|
||||
3. Traffic reverts to BLUE (v1.5.2) in <30 seconds
|
||||
4. Investigate issue in GREEN (offline)
|
||||
5. Fix and redeploy when ready
|
||||
|
|
@ -881,8 +881,8 @@ SECURITY LEVELS:
|
|||
|
||||
DEPLOYMENT STAGES:
|
||||
Development - Local Docker Compose
|
||||
Staging - Coolify (separate server)
|
||||
Production - Coolify (production server)
|
||||
Staging - Docker Compose (staging server)
|
||||
Production - Docker Compose (production server)
|
||||
|
||||
ABBREVIATIONS:
|
||||
RTO - Recovery Time Objective
|
||||
|
|
|
|||
|
|
@ -29,21 +29,24 @@
|
|||
- [ ] GitHub account (for CI/CD)
|
||||
- [ ] Supabase projects created (one per product)
|
||||
|
||||
### Step 1: Set up Docker Compose
|
||||
### Step 1: Set up Docker & Docker Compose
|
||||
|
||||
```bash
|
||||
# SSH into server
|
||||
ssh root@your-server-ip
|
||||
|
||||
# Set up Docker Compose (automated installer)
|
||||
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
|
||||
# Install Docker
|
||||
curl -fsSL https://get.docker.com | bash
|
||||
|
||||
# Install Docker Compose plugin
|
||||
apt-get update && apt-get install -y docker-compose-plugin
|
||||
|
||||
# Verify installation
|
||||
coolify --version
|
||||
docker --version
|
||||
docker compose version
|
||||
|
||||
# Access Docker Compose configuration
|
||||
# Navigate to: http://your-server-ip:8000
|
||||
# Create admin account
|
||||
# Set up deployment directory
|
||||
mkdir -p /opt/manacore && cd /opt/manacore
|
||||
```
|
||||
|
||||
### Step 2: Configure DNS
|
||||
|
|
@ -144,7 +147,7 @@ curl -X POST http://localhost:3001/api/auth/register \
|
|||
}'
|
||||
```
|
||||
|
||||
### Step 7: Configure SSL (Coolify Auto)
|
||||
### Step 7: Configure SSL (Let's Encrypt)
|
||||
|
||||
In Docker Compose configuration:
|
||||
|
||||
|
|
@ -282,8 +285,8 @@ docker compose --profile picture up -d
|
|||
# Step 7: Run database migrations
|
||||
docker compose exec picture-backend pnpm migration:run
|
||||
|
||||
# Step 8: Configure Coolify routing
|
||||
# In Docker Compose configuration:
|
||||
# Step 8: Configure Nginx routing
|
||||
# In Nginx configuration:
|
||||
# - Add new application: picture-backend
|
||||
# - Domain: api-picture.manacore.app
|
||||
# - Port: 3005
|
||||
|
|
@ -364,9 +367,9 @@ curl -f http://localhost:3012/api/health
|
|||
# Step 9: Smoke tests on green
|
||||
./scripts/smoke-test.sh http://localhost:3012
|
||||
|
||||
# Step 10: Switch traffic to green (Coolify)
|
||||
# In Docker Compose configuration or via API:
|
||||
coolify switch-deployment chat green
|
||||
# Step 10: Switch traffic to green (Nginx)
|
||||
# Update Nginx configuration to point to green:
|
||||
./scripts/switch-deployment.sh chat green
|
||||
|
||||
# Or manually update Nginx:
|
||||
sudo nano /etc/nginx/sites-available/api-chat.manacore.app
|
||||
|
|
@ -562,7 +565,7 @@ export async function up(db) {
|
|||
# (If blue environment still running)
|
||||
|
||||
# Switch traffic back to blue
|
||||
coolify switch-deployment chat blue
|
||||
./scripts/switch-deployment.sh chat blue
|
||||
|
||||
# Or manually update Nginx:
|
||||
sudo nano /etc/nginx/sites-available/api-chat.manacore.app
|
||||
|
|
@ -823,8 +826,8 @@ openssl s_client -connect api-chat.manacore.app:443 -servername api-chat.manacor
|
|||
# Manually renew certificate
|
||||
sudo certbot renew --force-renewal
|
||||
|
||||
# Or via Coolify:
|
||||
coolify ssl renew api-chat.manacore.app
|
||||
# Or check certbot logs:
|
||||
cat /var/log/letsencrypt/letsencrypt.log | tail -50
|
||||
|
||||
# Verification:
|
||||
curl -I https://api-chat.manacore.app
|
||||
|
|
@ -1003,7 +1006,7 @@ aws s3 cp env-backup-$(date +%Y%m%d).tar.gz.gpg \
|
|||
# Scenario: Complete server failure, restore to new server
|
||||
|
||||
# Step 1: Provision new server
|
||||
# Install Docker, Coolify, dependencies
|
||||
# Install Docker, Docker Compose, dependencies
|
||||
|
||||
# Step 2: Clone repository
|
||||
git clone https://github.com/manacore/manacore-monorepo.git
|
||||
|
|
|
|||
|
|
@ -1,709 +0,0 @@
|
|||
# Self-Hosting Guide - Manacore Monorepo
|
||||
|
||||
Komplette Anleitung zum Hosten aller Projekte auf eigener Infrastruktur (VPS).
|
||||
|
||||
## Projektübersicht
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────┐
|
||||
│ MANACORE MONOREPO │
|
||||
├─────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ MAERCHENZAUBER│ │ MANACORE │ │ MANADECK │ │ MEMORO │ │
|
||||
│ │ (Storyteller)│ │ (Auth Hub) │ │ (Deck App) │ │ (Voice App) │ │
|
||||
│ ├──────────────┤ ├──────────────┤ ├──────────────┤ ├──────────────┤ │
|
||||
│ │ • Web │ │ • Web │ │ • Web │ │ • Web │ │
|
||||
│ │ • Mobile │ │ • Mobile │ │ • Mobile │ │ • Mobile │ │
|
||||
│ │ • Landing │ │ • Landing │ │ • Landing │ │ • Landing │ │
|
||||
│ │ • Backend │ │ │ │ • Backend │ │ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ PICTURE │ │ ULOAD │ │
|
||||
│ │ (Canvas App) │ │(URL Shortener)│ │
|
||||
│ ├──────────────┤ ├──────────────┤ │
|
||||
│ │ • Web │ │ • Web │ │
|
||||
│ │ • Mobile │ │ │ │
|
||||
│ │ • Landing │ │ │ │
|
||||
│ └──────────────┘ └──────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Technologie-Stack pro Projekt
|
||||
|
||||
| Projekt | Web App | Landing | Backend | Mobile | Datenbank |
|
||||
| ------------------ | --------- | ------- | ------- | ------ | ------------------ |
|
||||
| **Maerchenzauber** | SvelteKit | Astro | NestJS | Expo | Supabase |
|
||||
| **Manacore** | SvelteKit | Astro | - | Expo | Supabase |
|
||||
| **Manadeck** | SvelteKit | Astro | NestJS | Expo | PostgreSQL |
|
||||
| **Memoro** | SvelteKit | Astro | - | Expo | Supabase |
|
||||
| **Picture** | SvelteKit | Astro | - | Expo | Supabase |
|
||||
| **uLoad** | SvelteKit | - | - | - | PostgreSQL + Redis |
|
||||
|
||||
---
|
||||
|
||||
## Deployment-Optionen im Überblick
|
||||
|
||||
### Option A: Single VPS mit Coolify (Empfohlen für Start)
|
||||
|
||||
- **Kosten:** ~€15-30/Monat
|
||||
- **Komplexität:** Niedrig
|
||||
- **Skalierung:** Begrenzt
|
||||
|
||||
### Option B: Multi-VPS mit Coolify
|
||||
|
||||
- **Kosten:** ~€50-100/Monat
|
||||
- **Komplexität:** Mittel
|
||||
- **Skalierung:** Gut
|
||||
|
||||
### Option C: Kubernetes (K3s)
|
||||
|
||||
- **Kosten:** ~€30-80/Monat
|
||||
- **Komplexität:** Hoch
|
||||
- **Skalierung:** Sehr gut
|
||||
|
||||
### Option D: Hybrid (Self-Hosted + Managed)
|
||||
|
||||
- **Kosten:** ~€20-50/Monat + Supabase
|
||||
- **Komplexität:** Niedrig-Mittel
|
||||
- **Skalierung:** Flexibel
|
||||
|
||||
---
|
||||
|
||||
# Option A: Single VPS mit Coolify
|
||||
|
||||
Die einfachste Lösung für den Start. Alle Services auf einem Server.
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Hetzner VPS (CX31+) │
|
||||
│ 4 vCPU, 8GB RAM, 80GB │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ COOLIFY │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ TRAEFIK │ │
|
||||
│ │ (Reverse Proxy + SSL) │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ ┌──────┴──────┐ ┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐ │
|
||||
│ │ Web Apps │ │ Backends │ │ Databases │ │ Landing │ │
|
||||
│ │ (Node.js) │ │ (NestJS) │ │ (PG+Redis)│ │ (Astro) │ │
|
||||
│ │ :3000-3005 │ │ :4000-4001│ │ :5432,6379│ │ :8080+ │ │
|
||||
│ └─────────────┘ └───────────┘ └───────────┘ └───────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Ressourcen-Anforderungen
|
||||
|
||||
| Komponente | RAM | CPU | Disk |
|
||||
| ----------------- | -------- | ------ | --------- |
|
||||
| PostgreSQL | 1GB | 0.5 | 10GB |
|
||||
| Redis | 256MB | 0.2 | 1GB |
|
||||
| Coolify | 512MB | 0.3 | 5GB |
|
||||
| Traefik | 128MB | 0.1 | - |
|
||||
| Pro Web App | 256MB | 0.3 | - |
|
||||
| Pro Backend | 512MB | 0.5 | - |
|
||||
| Pro Landing | 64MB | 0.1 | - |
|
||||
| **Gesamt (alle)** | **~6GB** | **~4** | **~30GB** |
|
||||
|
||||
**Empfohlener Server:** Hetzner CX31 (4 vCPU, 8GB RAM, 80GB) - €8.98/Monat
|
||||
|
||||
## Schritt-für-Schritt Setup
|
||||
|
||||
### 1. VPS bestellen und Coolify installieren
|
||||
|
||||
```bash
|
||||
# SSH zum Server
|
||||
ssh root@YOUR-IP
|
||||
|
||||
# System updaten
|
||||
apt update && apt upgrade -y
|
||||
|
||||
# Coolify installieren
|
||||
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
|
||||
```
|
||||
|
||||
### 2. Datenbank-Services erstellen
|
||||
|
||||
**PostgreSQL:**
|
||||
|
||||
```
|
||||
Name: shared-postgres
|
||||
Version: 16-alpine
|
||||
Databases: manacore, manadeck, uload
|
||||
```
|
||||
|
||||
**Redis:**
|
||||
|
||||
```
|
||||
Name: shared-redis
|
||||
Version: 7-alpine
|
||||
```
|
||||
|
||||
### 3. Projekte deployen
|
||||
|
||||
#### Deployment-Reihenfolge (wichtig!)
|
||||
|
||||
1. **Datenbanken** (PostgreSQL, Redis)
|
||||
2. **Backends** (Maerchenzauber, Manadeck)
|
||||
3. **Web Apps** (alle)
|
||||
4. **Landing Pages** (alle)
|
||||
|
||||
#### Konfiguration pro Projekt
|
||||
|
||||
**Alle SvelteKit Web Apps:**
|
||||
|
||||
```
|
||||
Base Directory: /
|
||||
Dockerfile: {projekt}/apps/web/Dockerfile # Falls vorhanden
|
||||
oder
|
||||
Build Pack: Nixpacks
|
||||
Build Command: cd {projekt}/apps/web && pnpm build
|
||||
Start Command: cd {projekt}/apps/web && node build
|
||||
Port: 3000
|
||||
```
|
||||
|
||||
**Alle Astro Landing Pages:**
|
||||
|
||||
```
|
||||
Build Pack: Static
|
||||
Base Directory: {projekt}/apps/landing
|
||||
Build Command: pnpm build
|
||||
Publish Directory: dist
|
||||
```
|
||||
|
||||
**NestJS Backends:**
|
||||
|
||||
```
|
||||
Base Directory: /
|
||||
Dockerfile: {projekt}/apps/backend/Dockerfile
|
||||
oder
|
||||
Dockerfile: {projekt}/backend/Dockerfile
|
||||
Port: 4000
|
||||
```
|
||||
|
||||
### 4. Domain-Mapping
|
||||
|
||||
| Service | Domain | Port |
|
||||
| ---------------------- | --------------------- | ---- |
|
||||
| uload-web | ulo.ad | 3000 |
|
||||
| maerchenzauber-web | app.maerchenzauber.de | 3001 |
|
||||
| maerchenzauber-landing | maerchenzauber.de | 8080 |
|
||||
| maerchenzauber-backend | api.maerchenzauber.de | 4000 |
|
||||
| manacore-web | app.manacore.io | 3002 |
|
||||
| manacore-landing | manacore.io | 8081 |
|
||||
| manadeck-web | app.manadeck.de | 3003 |
|
||||
| manadeck-landing | manadeck.de | 8082 |
|
||||
| manadeck-backend | api.manadeck.de | 4001 |
|
||||
| memoro-web | app.memoro.ai | 3004 |
|
||||
| memoro-landing | memoro.ai | 8083 |
|
||||
| picture-web | app.picture.io | 3005 |
|
||||
| picture-landing | picture.io | 8084 |
|
||||
|
||||
---
|
||||
|
||||
# Option B: Multi-VPS mit Coolify
|
||||
|
||||
Bessere Isolation und Skalierung durch mehrere Server.
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ DNS / CDN │
|
||||
│ (Cloudflare) │
|
||||
└────────┬────────┘
|
||||
│
|
||||
┌───────────────────────────┼───────────────────────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
||||
│ VPS 1 │ │ VPS 2 │ │ VPS 3 │
|
||||
│ (Apps) │ │ (Backends) │ │ (Databases) │
|
||||
│ CX21 │ │ CX21 │ │ CX31 │
|
||||
├───────────────┤ ├───────────────┤ ├───────────────┤
|
||||
│ • Web Apps │ ◄─────► │ • NestJS APIs │ ◄─────► │ • PostgreSQL │
|
||||
│ • Landing │ │ • Workers │ │ • Redis │
|
||||
│ Pages │ │ │ │ • Backups │
|
||||
└───────────────┘ └───────────────┘ └───────────────┘
|
||||
```
|
||||
|
||||
## Server-Aufteilung
|
||||
|
||||
### VPS 1: Frontend (CX21 - €4.49/Monat)
|
||||
|
||||
- Alle SvelteKit Web Apps
|
||||
- Alle Astro Landing Pages
|
||||
- Traefik Reverse Proxy
|
||||
|
||||
### VPS 2: Backends (CX21 - €4.49/Monat)
|
||||
|
||||
- Maerchenzauber NestJS Backend
|
||||
- Manadeck NestJS Backend
|
||||
- Background Workers
|
||||
|
||||
### VPS 3: Datenbanken (CX31 - €8.98/Monat)
|
||||
|
||||
- PostgreSQL (shared)
|
||||
- Redis (shared)
|
||||
- Automated Backups
|
||||
|
||||
**Gesamtkosten:** ~€18/Monat
|
||||
|
||||
## Einrichtung
|
||||
|
||||
### VPS 3 (Datenbanken) zuerst
|
||||
|
||||
```bash
|
||||
# Coolify installieren
|
||||
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
|
||||
|
||||
# PostgreSQL mit externem Zugriff
|
||||
# In Coolify: Network → Enable External Access
|
||||
```
|
||||
|
||||
### VPS 2 (Backends)
|
||||
|
||||
```bash
|
||||
# Coolify installieren
|
||||
# Backends deployen mit DATABASE_URL zu VPS 3
|
||||
```
|
||||
|
||||
### VPS 1 (Frontends)
|
||||
|
||||
```bash
|
||||
# Coolify installieren
|
||||
# Web Apps deployen mit API_URL zu VPS 2
|
||||
```
|
||||
|
||||
## Netzwerk-Sicherheit
|
||||
|
||||
```bash
|
||||
# Auf VPS 3 (Datenbanken): Nur VPS 1+2 erlauben
|
||||
ufw allow from VPS1-IP to any port 5432
|
||||
ufw allow from VPS2-IP to any port 5432
|
||||
ufw allow from VPS1-IP to any port 6379
|
||||
ufw allow from VPS2-IP to any port 6379
|
||||
ufw deny 5432
|
||||
ufw deny 6379
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Option C: Kubernetes mit K3s
|
||||
|
||||
Für maximale Skalierung und Automatisierung.
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ K3s Cluster │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────┐ │
|
||||
│ │ INGRESS (Traefik) │ │
|
||||
│ └────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────────────────────────┼───────────────────────────────┐ │
|
||||
│ │ │ │ │
|
||||
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
||||
│ │ │ Namespace │ │ Namespace │ │ Namespace │ │ │
|
||||
│ │ │ uload │ │ maerchen- │ │ manadeck │ │ │
|
||||
│ │ │ │ │ zauber │ │ │ │ │
|
||||
│ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │
|
||||
│ │ │ │ web:3 │ │ │ │ web:2 │ │ │ │ web:2 │ │ │ │
|
||||
│ │ │ │ replicas│ │ │ │ backend │ │ │ │ backend │ │ │ │
|
||||
│ │ │ └─────────┘ │ │ │ landing │ │ │ │ landing │ │ │ │
|
||||
│ │ └─────────────┘ │ └─────────┘ │ │ └─────────┘ │ │ │
|
||||
│ │ └─────────────┘ └─────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ Shared Services │ │ │
|
||||
│ │ │ PostgreSQL (StatefulSet) │ Redis (StatefulSet) │ │ │
|
||||
│ │ └─────────────────────────────────────────────────┘ │ │
|
||||
│ └───────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ Node 1 (CX21) Node 2 (CX21) Node 3 (CX21) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## K3s Setup
|
||||
|
||||
### Master Node installieren
|
||||
|
||||
```bash
|
||||
# Auf Node 1
|
||||
curl -sfL https://get.k3s.io | sh -
|
||||
|
||||
# Token für Worker holen
|
||||
cat /var/lib/rancher/k3s/server/node-token
|
||||
```
|
||||
|
||||
### Worker Nodes hinzufügen
|
||||
|
||||
```bash
|
||||
# Auf Node 2 und 3
|
||||
curl -sfL https://get.k3s.io | K3S_URL=https://NODE1-IP:6443 K3S_TOKEN=TOKEN sh -
|
||||
```
|
||||
|
||||
### Helm Charts deployen
|
||||
|
||||
```yaml
|
||||
# values-uload.yaml
|
||||
replicaCount: 2
|
||||
image:
|
||||
repository: ghcr.io/your-org/uload-web
|
||||
tag: latest
|
||||
service:
|
||||
port: 3000
|
||||
ingress:
|
||||
enabled: true
|
||||
hosts:
|
||||
- host: ulo.ad
|
||||
paths:
|
||||
- path: /
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: url
|
||||
```
|
||||
|
||||
```bash
|
||||
helm install uload ./charts/sveltekit -f values-uload.yaml
|
||||
```
|
||||
|
||||
## Vorteile K8s
|
||||
|
||||
- Auto-Scaling bei Last
|
||||
- Rolling Updates ohne Downtime
|
||||
- Self-Healing bei Ausfällen
|
||||
- Resource Limits pro App
|
||||
|
||||
## Nachteile K8s
|
||||
|
||||
- Höhere Komplexität
|
||||
- Mehr Overhead (RAM für K8s selbst)
|
||||
- Lernkurve
|
||||
|
||||
---
|
||||
|
||||
# Option D: Hybrid (Self-Hosted + Managed)
|
||||
|
||||
Kombination aus Self-Hosting und Managed Services für beste Balance.
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ MANAGED SERVICES │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ SUPABASE │ │ CLOUDFLARE │ │ VERCEL/ │ │
|
||||
│ │ (Database) │ │ (CDN) │ │ NETLIFY │ │
|
||||
│ │ PostgreSQL │ │ DNS, Cache │ │ (Landing) │ │
|
||||
│ │ Auth, Store │ │ DDoS Prot. │ │ Static │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │ │ │ │
|
||||
└─────────┼──────────────────┼──────────────────┼──────────────────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ SELF-HOSTED (VPS) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ Hetzner CX21 │ │
|
||||
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
|
||||
│ │ │ Web Apps │ │ Backends │ │ uLoad │ │ │
|
||||
│ │ │ (SvelteKit)│ │ (NestJS) │ │ + DB │ │ │
|
||||
│ │ └────────────┘ └────────────┘ └────────────┘ │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Was wo hosten?
|
||||
|
||||
### Managed Services (empfohlen)
|
||||
|
||||
| Service | Anbieter | Kosten | Grund |
|
||||
| ------------- | -------------- | ---------- | ------------------------- |
|
||||
| Datenbank | Supabase | Free-$25/M | Auth + Realtime inklusive |
|
||||
| Landing Pages | Vercel/Netlify | Free | CDN + Edge |
|
||||
| CDN | Cloudflare | Free | DDoS + Caching |
|
||||
| Email | Resend | Free-$20/M | Deliverability |
|
||||
| Payments | Stripe | % per Tx | Compliance |
|
||||
|
||||
### Self-Hosted (VPS)
|
||||
|
||||
| Service | Grund |
|
||||
| -------- | -------------------------------------- |
|
||||
| Web Apps | Volle Kontrolle, günstiger bei Traffic |
|
||||
| Backends | Custom Code, API Keys |
|
||||
| uLoad | Komplett eigene Infra gewünscht |
|
||||
| Redis | Falls benötigt |
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Supabase Projekt erstellen
|
||||
|
||||
Für: Maerchenzauber, Manacore, Memoro, Picture
|
||||
|
||||
```bash
|
||||
# Supabase CLI
|
||||
supabase init
|
||||
supabase db push
|
||||
```
|
||||
|
||||
### 2. Landing Pages auf Vercel
|
||||
|
||||
```bash
|
||||
# In jedem Landing-Projekt
|
||||
cd maerchenzauber/apps/landing
|
||||
vercel deploy --prod
|
||||
```
|
||||
|
||||
### 3. VPS für Web Apps + Backends
|
||||
|
||||
```bash
|
||||
# Coolify auf Hetzner CX21
|
||||
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
|
||||
|
||||
# Apps deployen mit Supabase URLs
|
||||
```
|
||||
|
||||
## Kosten-Vergleich
|
||||
|
||||
| Komponente | Full Self-Hosted | Hybrid |
|
||||
| ---------- | ---------------- | ------------------ |
|
||||
| VPS | €9-18/Monat | €4.50/Monat |
|
||||
| Supabase | - | Free-€25/Monat |
|
||||
| Vercel | - | Free |
|
||||
| Cloudflare | - | Free |
|
||||
| **Gesamt** | **€9-18/Monat** | **€4.50-30/Monat** |
|
||||
|
||||
---
|
||||
|
||||
# Dockerfiles für alle Projekte
|
||||
|
||||
## SvelteKit Web Apps (Template)
|
||||
|
||||
Erstelle für jedes Projekt ohne Dockerfile:
|
||||
|
||||
```dockerfile
|
||||
# {projekt}/apps/web/Dockerfile
|
||||
|
||||
FROM node:20-alpine AS builder
|
||||
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate
|
||||
WORKDIR /app
|
||||
|
||||
# Monorepo files
|
||||
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
|
||||
COPY {projekt}/apps/web/ ./{projekt}/apps/web/
|
||||
COPY packages/ ./packages/
|
||||
|
||||
# Install and build
|
||||
RUN pnpm install --filter @{projekt}/web... --shamefully-hoist
|
||||
WORKDIR /app/{projekt}/apps/web
|
||||
RUN pnpm build
|
||||
|
||||
# Runner
|
||||
FROM node:20-alpine
|
||||
RUN adduser -D sveltekit
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/{projekt}/apps/web/build ./build
|
||||
COPY --from=builder /app/{projekt}/apps/web/package.json ./
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
|
||||
USER sveltekit
|
||||
ENV NODE_ENV=production PORT=3000
|
||||
EXPOSE 3000
|
||||
CMD ["node", "build"]
|
||||
```
|
||||
|
||||
## Astro Landing Pages
|
||||
|
||||
```dockerfile
|
||||
# {projekt}/apps/landing/Dockerfile
|
||||
|
||||
FROM node:20-alpine AS builder
|
||||
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
|
||||
COPY {projekt}/apps/landing/ ./{projekt}/apps/landing/
|
||||
COPY packages/ ./packages/
|
||||
|
||||
RUN pnpm install --filter @{projekt}/landing... --shamefully-hoist
|
||||
WORKDIR /app/{projekt}/apps/landing
|
||||
RUN pnpm build
|
||||
|
||||
# Nginx for static files
|
||||
FROM nginx:alpine
|
||||
COPY --from=builder /app/{projekt}/apps/landing/dist /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
```
|
||||
|
||||
## NestJS Backends
|
||||
|
||||
Bereits vorhanden in:
|
||||
|
||||
- `maerchenzauber/apps/backend/Dockerfile`
|
||||
- `manadeck/backend/Dockerfile`
|
||||
|
||||
---
|
||||
|
||||
# Environment Variables
|
||||
|
||||
## Gemeinsame Variablen (alle Projekte)
|
||||
|
||||
```env
|
||||
NODE_ENV=production
|
||||
```
|
||||
|
||||
## Supabase-basierte Projekte
|
||||
|
||||
```env
|
||||
# Maerchenzauber, Manacore, Memoro, Picture
|
||||
PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
||||
PUBLIC_SUPABASE_ANON_KEY=eyJxx...
|
||||
SUPABASE_SERVICE_ROLE_KEY=eyJxx... # Nur Backend
|
||||
```
|
||||
|
||||
## PostgreSQL-basierte Projekte
|
||||
|
||||
```env
|
||||
# Manadeck, uLoad
|
||||
DATABASE_URL=postgresql://user:pass@host:5432/db
|
||||
```
|
||||
|
||||
## Projekt-spezifische Variablen
|
||||
|
||||
### Maerchenzauber Backend
|
||||
|
||||
```env
|
||||
AZURE_OPENAI_ENDPOINT=https://xxx.openai.azure.com
|
||||
AZURE_OPENAI_API_KEY=xxx
|
||||
GOOGLE_GEMINI_API_KEY=xxx
|
||||
REPLICATE_API_TOKEN=xxx
|
||||
GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
|
||||
```
|
||||
|
||||
### Manadeck Backend
|
||||
|
||||
```env
|
||||
GOOGLE_GEMINI_API_KEY=xxx
|
||||
```
|
||||
|
||||
### uLoad
|
||||
|
||||
```env
|
||||
REDIS_URL=redis://localhost:6379
|
||||
STRIPE_SECRET_KEY=sk_live_xxx
|
||||
STRIPE_WEBHOOK_SECRET=whsec_xxx
|
||||
RESEND_API_KEY=re_xxx
|
||||
R2_ACCESS_KEY_ID=xxx
|
||||
R2_SECRET_ACCESS_KEY=xxx
|
||||
R2_BUCKET_NAME=xxx
|
||||
R2_ENDPOINT=https://xxx.r2.cloudflarestorage.com
|
||||
AUTH_SECRET=xxx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Checkliste: Komplettes Self-Hosting
|
||||
|
||||
## Infrastruktur
|
||||
|
||||
- [ ] VPS bestellt (Hetzner CX21/CX31)
|
||||
- [ ] SSH-Zugang eingerichtet
|
||||
- [ ] Coolify installiert
|
||||
- [ ] Firewall konfiguriert
|
||||
|
||||
## Datenbanken
|
||||
|
||||
- [ ] PostgreSQL läuft
|
||||
- [ ] Redis läuft (falls benötigt)
|
||||
- [ ] Backups eingerichtet
|
||||
- [ ] Connection Strings notiert
|
||||
|
||||
## Projekte (für jedes)
|
||||
|
||||
- [ ] Dockerfile erstellt/geprüft
|
||||
- [ ] Environment Variables gesetzt
|
||||
- [ ] Domain konfiguriert
|
||||
- [ ] SSL-Zertifikat aktiv
|
||||
- [ ] Health-Check funktioniert
|
||||
|
||||
## DNS (für jede Domain)
|
||||
|
||||
- [ ] A-Record auf Server-IP
|
||||
- [ ] www CNAME (optional)
|
||||
- [ ] Propagation geprüft
|
||||
|
||||
## Monitoring
|
||||
|
||||
- [ ] Logs erreichbar
|
||||
- [ ] Alerting eingerichtet (optional)
|
||||
- [ ] Uptime-Monitoring (optional)
|
||||
|
||||
## Backups
|
||||
|
||||
- [ ] Datenbank-Backup automatisiert
|
||||
- [ ] Backup-Test durchgeführt
|
||||
- [ ] Offsite-Backup (optional)
|
||||
|
||||
---
|
||||
|
||||
# Empfehlung
|
||||
|
||||
## Für den Start: Option D (Hybrid)
|
||||
|
||||
1. **Supabase** für Datenbank + Auth (Free Tier)
|
||||
2. **Vercel/Netlify** für Landing Pages (Free)
|
||||
3. **Hetzner CX21** für Web Apps + Backends (€4.50/Monat)
|
||||
4. **Cloudflare** für DNS + CDN (Free)
|
||||
|
||||
**Vorteile:**
|
||||
|
||||
- Schneller Start
|
||||
- Geringe Kosten
|
||||
- Managed Auth & Realtime
|
||||
- Einfache Skalierung später
|
||||
|
||||
## Für Wachstum: Option B (Multi-VPS)
|
||||
|
||||
Wenn Traffic steigt:
|
||||
|
||||
1. Datenbanken auf eigenen VPS migrieren
|
||||
2. Frontend/Backend trennen
|
||||
3. Load Balancing hinzufügen
|
||||
|
||||
## Für Enterprise: Option C (Kubernetes)
|
||||
|
||||
Wenn benötigt:
|
||||
|
||||
- Auto-Scaling
|
||||
- Zero-Downtime Deployments
|
||||
- Multi-Region
|
||||
|
||||
---
|
||||
|
||||
# Support & Links
|
||||
|
||||
- **Coolify Docs:** https://coolify.io/docs
|
||||
- **Hetzner:** https://www.hetzner.com/cloud
|
||||
- **Supabase:** https://supabase.com/docs
|
||||
- **K3s:** https://k3s.io
|
||||
- **Traefik:** https://doc.traefik.io/traefik/
|
||||
|
|
@ -1,451 +0,0 @@
|
|||
# uload Deployment Guide
|
||||
|
||||
Schritt-für-Schritt Anleitung zum Deployment von uload mit Coolify auf Hetzner VPS.
|
||||
|
||||
## Architektur
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Hetzner VPS │
|
||||
│ ┌───────────────────────────────────────────────────────────┐ │
|
||||
│ │ Coolify │ │
|
||||
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
|
||||
│ │ │ uload │ │ PostgreSQL │ │ Redis │ │ │
|
||||
│ │ │ (Node) │ │ (16) │ │ (7) │ │ │
|
||||
│ │ │ :3000 │ │ :5432 │ │ :6379 │ │ │
|
||||
│ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ └────────────────┴──────────────────┘ │ │
|
||||
│ │ Traefik (SSL/Proxy) │ │
|
||||
│ │ :80 / :443 │ │
|
||||
│ └───────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
https://ulo.ad
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- [ ] Hetzner VPS (mindestens CX21: 2 vCPU, 4GB RAM, 40GB SSD)
|
||||
- [ ] Domain mit DNS-Zugang (z.B. ulo.ad)
|
||||
- [ ] GitHub Account mit Zugriff auf das Repository
|
||||
- [ ] Accounts für externe Services:
|
||||
- Resend (Email)
|
||||
- Stripe (Payments)
|
||||
- Cloudflare R2 (Storage)
|
||||
|
||||
---
|
||||
|
||||
## Schritt 1: Hetzner VPS einrichten
|
||||
|
||||
### 1.1 Server erstellen
|
||||
|
||||
1. Gehe zu [Hetzner Cloud Console](https://console.hetzner.cloud)
|
||||
2. Erstelle neues Projekt oder wähle bestehendes
|
||||
3. Klicke **Add Server**
|
||||
4. Wähle:
|
||||
- **Location:** Falkenstein oder Nürnberg (DE)
|
||||
- **Image:** Ubuntu 22.04
|
||||
- **Type:** CX21 (2 vCPU, 4GB RAM) oder größer
|
||||
- **SSH Key:** Füge deinen öffentlichen SSH-Key hinzu
|
||||
5. Klicke **Create & Buy Now**
|
||||
6. Notiere die **IP-Adresse**
|
||||
|
||||
### 1.2 Mit Server verbinden
|
||||
|
||||
```bash
|
||||
ssh root@DEINE-SERVER-IP
|
||||
```
|
||||
|
||||
### 1.3 System updaten
|
||||
|
||||
```bash
|
||||
apt update && apt upgrade -y
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Schritt 2: Coolify installieren
|
||||
|
||||
### 2.1 Installation
|
||||
|
||||
```bash
|
||||
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
|
||||
```
|
||||
|
||||
Die Installation dauert ca. 2-5 Minuten.
|
||||
|
||||
### 2.2 Coolify öffnen
|
||||
|
||||
1. Öffne im Browser: `http://DEINE-SERVER-IP:8000`
|
||||
2. Erstelle Admin-Account (E-Mail + Passwort)
|
||||
3. Wähle **Self-hosted** als Instance Type
|
||||
4. Der Server "localhost" wird automatisch hinzugefügt
|
||||
|
||||
---
|
||||
|
||||
## Schritt 3: PostgreSQL Datenbank erstellen
|
||||
|
||||
### 3.1 In Coolify
|
||||
|
||||
1. Klicke **+ New Resource**
|
||||
2. Wähle **Database**
|
||||
3. Wähle **PostgreSQL**
|
||||
4. Konfiguriere:
|
||||
- **Name:** `uload-postgres`
|
||||
- **Version:** `16-alpine`
|
||||
- **Database Name:** `uload`
|
||||
- **Database User:** `uload`
|
||||
- **Password:** (automatisch generiert oder eigenes)
|
||||
5. Klicke **Start**
|
||||
|
||||
### 3.2 Connection String notieren
|
||||
|
||||
Nach dem Start findest du unter **Connect** die Internal URL:
|
||||
|
||||
```
|
||||
postgresql://uload:PASSWORT@uload-postgres:5432/uload
|
||||
```
|
||||
|
||||
**Wichtig:** Kopiere diese URL - du brauchst sie später!
|
||||
|
||||
---
|
||||
|
||||
## Schritt 4: Redis erstellen (optional, aber empfohlen)
|
||||
|
||||
### 4.1 In Coolify
|
||||
|
||||
1. Klicke **+ New Resource**
|
||||
2. Wähle **Database**
|
||||
3. Wähle **Redis**
|
||||
4. Konfiguriere:
|
||||
- **Name:** `uload-redis`
|
||||
- **Version:** `7-alpine`
|
||||
5. Klicke **Start**
|
||||
|
||||
### 4.2 Connection String notieren
|
||||
|
||||
```
|
||||
redis://uload-redis:6379
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Schritt 5: GitHub Repository verbinden
|
||||
|
||||
### 5.1 GitHub App erstellen
|
||||
|
||||
1. In Coolify: Gehe zu **Sources** (linke Sidebar)
|
||||
2. Klicke **+ Add**
|
||||
3. Wähle **GitHub App**
|
||||
4. Klicke **Register GitHub App**
|
||||
5. Du wirst zu GitHub weitergeleitet
|
||||
6. Gib der App einen Namen (z.B. "coolify-uload")
|
||||
7. Klicke **Create GitHub App**
|
||||
8. Installiere die App für dein Repository
|
||||
|
||||
### 5.2 Repository-Zugriff gewähren
|
||||
|
||||
1. Wähle **Only select repositories**
|
||||
2. Wähle `manacore-monorepo`
|
||||
3. Klicke **Install**
|
||||
|
||||
---
|
||||
|
||||
## Schritt 6: uload Application erstellen
|
||||
|
||||
### 6.1 Neue Application
|
||||
|
||||
1. Klicke **+ New Resource**
|
||||
2. Wähle **Application**
|
||||
3. Wähle deine **GitHub App** als Source
|
||||
4. Wähle das Repository `manacore-monorepo`
|
||||
5. Wähle Branch: `main`
|
||||
|
||||
### 6.2 Build-Konfiguration (WICHTIG!)
|
||||
|
||||
Da uload Teil eines Monorepos ist, muss die Build-Konfiguration genau so sein:
|
||||
|
||||
| Einstellung | Wert |
|
||||
| ----------------------- | -------------------------- |
|
||||
| **Base Directory** | `/` (leer lassen oder `/`) |
|
||||
| **Build Pack** | Dockerfile |
|
||||
| **Dockerfile Location** | `uload/Dockerfile` |
|
||||
| **Port Exposes** | `3000` |
|
||||
|
||||
**Warum `/` als Base Directory?**
|
||||
Das Dockerfile benötigt Zugriff auf:
|
||||
|
||||
- `uload/apps/web/` (die App)
|
||||
- `packages/shared-*` (gemeinsame Packages)
|
||||
- `pnpm-workspace.yaml` und `pnpm-lock.yaml` (Workspace-Config)
|
||||
|
||||
---
|
||||
|
||||
## Schritt 7: Environment Variables setzen
|
||||
|
||||
### 7.1 In Coolify
|
||||
|
||||
Gehe zu deiner Application → **Environment Variables** → **Add Variable**
|
||||
|
||||
### 7.2 Erforderliche Variablen
|
||||
|
||||
```env
|
||||
# === APP ===
|
||||
NODE_ENV=production
|
||||
PORT=3000
|
||||
HOST=0.0.0.0
|
||||
ORIGIN=https://ulo.ad
|
||||
|
||||
# === DATABASE ===
|
||||
# Von Schritt 3.2 - PostgreSQL Internal URL
|
||||
DATABASE_URL=postgresql://uload:DEIN-PASSWORT@uload-postgres:5432/uload
|
||||
|
||||
# === REDIS (optional) ===
|
||||
# Von Schritt 4.2
|
||||
REDIS_URL=redis://uload-redis:6379
|
||||
|
||||
# === AUTH ===
|
||||
# Generiere mit: openssl rand -base64 32
|
||||
AUTH_SECRET=GENERIERE-EINEN-SICHEREN-STRING-HIER
|
||||
|
||||
# === EMAIL (Resend) ===
|
||||
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
# === PAYMENTS (Stripe) ===
|
||||
STRIPE_SECRET_KEY=sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
# === STORAGE (Cloudflare R2) ===
|
||||
R2_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
R2_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
R2_BUCKET_NAME=uload-uploads
|
||||
R2_ENDPOINT=https://xxxxxxxxxx.r2.cloudflarestorage.com
|
||||
```
|
||||
|
||||
### 7.3 AUTH_SECRET generieren
|
||||
|
||||
Auf deinem lokalen Rechner:
|
||||
|
||||
```bash
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
Kopiere das Ergebnis als `AUTH_SECRET`.
|
||||
|
||||
---
|
||||
|
||||
## Schritt 8: Domain konfigurieren
|
||||
|
||||
### 8.1 DNS-Einträge setzen
|
||||
|
||||
Bei deinem DNS-Provider (z.B. Cloudflare, Namecheap):
|
||||
|
||||
| Type | Name | Value | TTL |
|
||||
| ---- | ---- | --------------- | ---- |
|
||||
| A | @ | DEINE-SERVER-IP | 3600 |
|
||||
| A | www | DEINE-SERVER-IP | 3600 |
|
||||
|
||||
### 8.2 Domain in Coolify hinzufügen
|
||||
|
||||
1. Gehe zu deiner Application → **Settings**
|
||||
2. Unter **Domains** klicke **+ Add**
|
||||
3. Gib ein: `ulo.ad`
|
||||
4. Aktiviere: **Generate SSL Certificate** (Let's Encrypt)
|
||||
5. Optional: Füge auch `www.ulo.ad` hinzu mit Redirect
|
||||
|
||||
### 8.3 Warten
|
||||
|
||||
DNS-Änderungen können 5-30 Minuten dauern. SSL-Zertifikate werden automatisch erstellt.
|
||||
|
||||
---
|
||||
|
||||
## Schritt 9: Deployment starten
|
||||
|
||||
### 9.1 Erster Deploy
|
||||
|
||||
1. Gehe zu deiner Application
|
||||
2. Klicke **Deploy**
|
||||
3. Warte auf den Build (ca. 3-5 Minuten)
|
||||
|
||||
### 9.2 Build-Logs überwachen
|
||||
|
||||
Klicke auf das laufende Deployment um die Logs zu sehen.
|
||||
|
||||
**Erfolgreicher Build zeigt:**
|
||||
|
||||
```
|
||||
✔ done
|
||||
Listening on http://0.0.0.0:3000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Schritt 10: Datenbank-Migration
|
||||
|
||||
### 10.1 Nach erstem Deployment
|
||||
|
||||
Die Datenbank-Tabellen müssen erstellt werden:
|
||||
|
||||
1. In Coolify: Gehe zu deiner Application → **Terminal**
|
||||
2. Oder via SSH:
|
||||
|
||||
```bash
|
||||
# Container-Name finden
|
||||
docker ps | grep uload
|
||||
|
||||
# In Container gehen
|
||||
docker exec -it CONTAINER-NAME sh
|
||||
|
||||
# Migration ausführen
|
||||
npx drizzle-kit push
|
||||
```
|
||||
|
||||
### 10.2 Alternative: Pre-Deploy Command
|
||||
|
||||
In Coolify → Application → **Settings** → **Pre-Deploy Command**:
|
||||
|
||||
```bash
|
||||
cd /app && npx drizzle-kit push
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Schritt 11: Verifizieren
|
||||
|
||||
### 11.1 Health Check
|
||||
|
||||
```bash
|
||||
curl https://ulo.ad/api/health
|
||||
```
|
||||
|
||||
Erwartete Antwort:
|
||||
|
||||
```json
|
||||
{ "status": "ok", "timestamp": "2025-11-25T12:00:00.000Z", "uptime": 123.45 }
|
||||
```
|
||||
|
||||
### 11.2 Website öffnen
|
||||
|
||||
Öffne `https://ulo.ad` im Browser.
|
||||
|
||||
---
|
||||
|
||||
## Automatische Deployments
|
||||
|
||||
### Webhook (Standard)
|
||||
|
||||
Coolify erstellt automatisch einen GitHub Webhook. Bei jedem Push auf `main` wird automatisch deployed.
|
||||
|
||||
### Manuelles Deployment
|
||||
|
||||
In Coolify: Application → **Redeploy**
|
||||
|
||||
---
|
||||
|
||||
## Wartung & Monitoring
|
||||
|
||||
### Logs anzeigen
|
||||
|
||||
**In Coolify:**
|
||||
Application → **Logs**
|
||||
|
||||
**Via SSH:**
|
||||
|
||||
```bash
|
||||
docker logs -f $(docker ps -qf "name=uload")
|
||||
```
|
||||
|
||||
### Container neustarten
|
||||
|
||||
In Coolify: Application → **Restart**
|
||||
|
||||
### Datenbank Backup
|
||||
|
||||
```bash
|
||||
# Manuelles Backup
|
||||
docker exec uload-postgres pg_dump -U uload uload > backup_$(date +%Y%m%d).sql
|
||||
|
||||
# Backup wiederherstellen
|
||||
cat backup_20251125.sql | docker exec -i uload-postgres psql -U uload uload
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build schlägt fehl
|
||||
|
||||
| Problem | Lösung |
|
||||
| -------------------------- | ---------------------------------------- |
|
||||
| "Cannot find package" | Prüfe Base Directory (muss `/` sein) |
|
||||
| "pnpm-lock.yaml not found" | Prüfe dass pnpm-lock.yaml im Repo ist |
|
||||
| Timeout beim Build | Erhöhe Build-Timeout in Coolify Settings |
|
||||
|
||||
### Container startet nicht
|
||||
|
||||
| Problem | Lösung |
|
||||
| ---------------------------- | ----------------------------------------- |
|
||||
| "Missing API key" | Prüfe RESEND_API_KEY Environment Variable |
|
||||
| "Cannot connect to database" | Prüfe DATABASE_URL (Internal URL!) |
|
||||
| Port already in use | Prüfe ob alter Container noch läuft |
|
||||
|
||||
### SSL-Zertifikat Fehler
|
||||
|
||||
1. Prüfe DNS-Einträge (A-Record auf Server-IP)
|
||||
2. Warte 5-10 Minuten
|
||||
3. In Coolify: Domain löschen und neu hinzufügen
|
||||
4. Prüfe ob Port 80 erreichbar ist (Firewall)
|
||||
|
||||
### Datenbank-Verbindung fehlgeschlagen
|
||||
|
||||
1. Prüfe ob PostgreSQL-Container läuft
|
||||
2. Verwende **Internal URL** (nicht External!)
|
||||
3. Teste Verbindung:
|
||||
```bash
|
||||
docker exec -it uload-postgres psql -U uload -d uload -c "SELECT 1"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checkliste Production-Ready
|
||||
|
||||
- [ ] Hetzner VPS erstellt und SSH funktioniert
|
||||
- [ ] Coolify installiert und Admin-Account erstellt
|
||||
- [ ] PostgreSQL läuft und CONNECTION_STRING notiert
|
||||
- [ ] Redis läuft (optional)
|
||||
- [ ] GitHub Repository verbunden
|
||||
- [ ] Application mit korrektem Dockerfile-Pfad erstellt
|
||||
- [ ] Alle Environment Variables gesetzt
|
||||
- [ ] AUTH_SECRET generiert (min. 32 Zeichen)
|
||||
- [ ] DNS A-Records konfiguriert
|
||||
- [ ] Domain in Coolify hinzugefügt
|
||||
- [ ] SSL-Zertifikat aktiv
|
||||
- [ ] Erster Deploy erfolgreich
|
||||
- [ ] Datenbank-Migration ausgeführt
|
||||
- [ ] Health-Check funktioniert (`/api/health`)
|
||||
- [ ] Website erreichbar
|
||||
|
||||
---
|
||||
|
||||
## Dateien im Repository
|
||||
|
||||
| Datei | Beschreibung |
|
||||
| ---------------------------------- | ------------------------ |
|
||||
| `uload/Dockerfile` | Multi-Stage Docker Build |
|
||||
| `uload/docker-compose.yml` | Lokale Entwicklung |
|
||||
| `uload/docker-compose.coolify.yml` | Coolify Deployment |
|
||||
| `uload/docker-compose.prod.yml` | Standalone Production |
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
Bei Problemen:
|
||||
|
||||
1. Coolify Logs prüfen
|
||||
2. Container Logs prüfen (`docker logs`)
|
||||
3. GitHub Issues: https://github.com/anthropics/claude-code/issues
|
||||
Loading…
Add table
Add a link
Reference in a new issue