From 972797dcfc7266825e798bede226f0aea70aba77 Mon Sep 17 00:00:00 2001 From: xpltd_admin Date: Fri, 3 Apr 2026 22:52:34 -0600 Subject: [PATCH] Create Deployment wiki page for fractafrag --- Deployment.md | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 Deployment.md diff --git a/Deployment.md b/Deployment.md new file mode 100644 index 0000000..f4ef4a9 --- /dev/null +++ b/Deployment.md @@ -0,0 +1,200 @@ +# Deployment + +| Meta | Value | +|------|-------| +| **Repo** | `xpltdco/fractafrag` | +| **Page** | `Deployment` | +| **Audience** | developers, agents, newcomers | +| **Last Updated** | 2026-04-04 | +| **Status** | current | + +## Docker Compose Stack + +Fractafrag runs as 8 Docker containers orchestrated by `docker-compose.yml`. + +### Services + +| Service | Image | Port | Health Check | +|---------|-------|------|-------------| +| **nginx** | nginx:alpine | 80 | — | +| **frontend** | node:20-alpine (custom) | 5173 | — | +| **api** | python:3.12-slim (custom) | 8000 | `curl -f http://localhost:8000/health` (10s interval) | +| **mcp** | python:3.12-slim (custom) | 3200 | — | +| **renderer** | node:20-slim + Chromium (custom) | 3100 | — | +| **worker** | reuses api image | — | — | +| **postgres** | pgvector/pgvector:pg16 | 5432 | `pg_isready -U fracta` (5s interval) | +| **redis** | redis:7-alpine | 6379 | `redis-cli ping` (5s interval) | + +### Startup Dependencies + +``` +postgres (healthy) ─┐ + ├─→ api (healthy) ─┬─→ nginx +redis (healthy) ────┘ ├─→ mcp + └─→ frontend ─→ nginx +postgres (healthy) ─┐ + ├─→ worker +redis (healthy) ────┘ +``` + +## Volume Mounts + +| Volume | Container Path | Purpose | Backup Priority | +|--------|---------------|---------|-----------------| +| `pgdata` (named) | `/var/lib/postgresql/data` | PostgreSQL data | **Critical** — all application state | +| `redisdata` (named) | `/data` | Redis AOF persistence | **Low** — regeneratable cache | +| `renders` (named) | `/renders` | Shader thumbnails/previews | **Medium** — regeneratable but slow | + +### Init Script Mount + +```yaml +./db/init.sql:/docker-entrypoint-initdb.d/01-init.sql:ro +``` + +This SQL file runs on first PostgreSQL startup only. It creates all tables, indexes, extensions, and the system user account. + +## Port Mappings + +| Port | Service | Protocol | Purpose | +|------|---------|----------|---------| +| 80 | nginx | HTTP | Main entry point (proxy to all services) | +| 8000 | api | HTTP | FastAPI backend (dev direct access) | +| 5173 | frontend | HTTP | Vite dev server (dev direct access) | +| 3200 | mcp | HTTP+SSE | MCP server (dev direct access) | +| 3100 | renderer | HTTP | Headless renderer (internal) | +| 5432 | postgres | TCP | PostgreSQL (dev direct access) | +| 6379 | redis | TCP | Redis (dev direct access) | + +> In production, only port 80 (nginx) should be exposed externally. Other ports are exposed in `docker-compose.override.yml` for development only. + +## Nginx Routing + +**Config file:** `services/nginx/conf/default.conf` + +| Location | Target | Timeout | Notes | +|----------|--------|---------|-------| +| `/` | `frontend:5173` | — | WebSocket upgrade for Vite HMR | +| `/api/*` | `api:8000/api/` | 120s | 10M body limit | +| `/mcp/*` | `mcp:3200/` | 600s | SSE support, no buffering | +| `/renders/*` | `/renders/` (volume alias) | — | 30-day cache, immutable | +| `/health` | direct 200 | — | Logging disabled | + +## xpltd Infrastructure Deployment + +On the xpltd infrastructure: + +### Traffic Flow + +``` +Client → Cloudflare (DNS: fractafrag.xpltd.co) + → nginx01:443 (TLS termination) + → ub01:80 (fractafrag nginx container) + → internal service routing +``` + +### DNS + +| Layer | Record | Value | +|-------|--------|-------| +| **Cloudflare** | `fractafrag.xpltd.co` CNAME | `dyndns.xpltd.co` | +| **AdGuard Home** | `*.xpltd.co` rewrite | `10.0.0.9` (nginx01) | + +## Health Checks + +### API Health + +```yaml +healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/health"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 15s +``` + +### PostgreSQL Health + +```yaml +healthcheck: + test: ["CMD-SHELL", "pg_isready -U fracta -d fractafrag"] + interval: 5s + timeout: 5s + retries: 5 +``` + +### Redis Health + +```yaml +healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 5s + retries: 5 +``` + +## Renderer Configuration + +The renderer service requires special Docker configuration: + +```yaml +renderer: + shm_size: '512mb' # Required for Chromium shared memory + environment: + - MAX_RENDER_DURATION=8 + - OUTPUT_DIR=/renders +``` + +Chromium runs in headless mode with software rendering (SwiftShader). No GPU passthrough required. + +## Redis Configuration + +```yaml +command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru +``` + +- **AOF persistence** enabled (append-only file) +- **256MB** max memory with LRU eviction +- Increase `--maxmemory` if running many concurrent Celery tasks + +## Logging + +All services write to stdout/stderr (captured by Docker logging driver). + +```bash +# All services +make logs +# or: docker compose logs -f + +# Specific service +docker compose logs -f api +docker compose logs -f worker +docker compose logs -f renderer +``` + +## Backup Considerations + +### What to Back Up + +| Data | Location | Strategy | +|------|----------|----------| +| **PostgreSQL** | `pgdata` volume | `pg_dump` for logical backup | +| **Render output** | `renders` volume | Optional — can be regenerated | +| **Redis** | `redisdata` volume | Optional — ephemeral cache | + +### PostgreSQL Backup + +```bash +# Logical backup (recommended) +docker compose exec postgres pg_dump -U fracta fractafrag > backup.sql + +# Restore +docker compose exec -T postgres psql -U fracta fractafrag < backup.sql +``` + +### Recovery + +1. `docker compose down` +2. Remove volumes if doing a clean restore: `docker volume rm fractafrag_pgdata` +3. `docker compose up -d postgres` (waits for healthy) +4. Restore: `docker compose exec -T postgres psql -U fracta fractafrag < backup.sql` +5. `docker compose up -d` (start remaining services) \ No newline at end of file