Create Deployment wiki page for fractafrag
parent
c640f13e15
commit
972797dcfc
1 changed files with 200 additions and 0 deletions
200
Deployment.md
Normal file
200
Deployment.md
Normal file
|
|
@ -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)
|
||||
Loading…
Add table
Reference in a new issue