feat: Created full Docker Compose project (xpltd_chrysopedia) with Post…
- "docker-compose.yml" - ".env.example" - "docker/Dockerfile.api" - "docker/Dockerfile.web" - "docker/nginx.conf" - "backend/main.py" - "backend/requirements.txt" - "config/canonical_tags.yaml" GSD-Task: S01/T01
This commit is contained in:
parent
0904939660
commit
c404270f49
12 changed files with 332 additions and 0 deletions
37
.env.example
Normal file
37
.env.example
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
# ─── Chrysopedia Environment Variables ───
|
||||||
|
|
||||||
|
# PostgreSQL
|
||||||
|
POSTGRES_USER=chrysopedia
|
||||||
|
POSTGRES_PASSWORD=changeme
|
||||||
|
POSTGRES_DB=chrysopedia
|
||||||
|
DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@chrysopedia-db:5432/${POSTGRES_DB}
|
||||||
|
|
||||||
|
# Redis (Celery broker)
|
||||||
|
REDIS_URL=redis://chrysopedia-redis:6379/0
|
||||||
|
|
||||||
|
# LLM endpoint (OpenAI-compatible)
|
||||||
|
LLM_API_URL=https://friend-openwebui.example.com/api
|
||||||
|
LLM_API_KEY=sk-changeme
|
||||||
|
LLM_MODEL=qwen2.5-72b
|
||||||
|
LLM_FALLBACK_URL=http://localhost:11434/v1
|
||||||
|
LLM_FALLBACK_MODEL=qwen2.5:14b-q8_0
|
||||||
|
|
||||||
|
# Embedding endpoint
|
||||||
|
EMBEDDING_API_URL=http://localhost:11434/v1
|
||||||
|
EMBEDDING_MODEL=nomic-embed-text
|
||||||
|
|
||||||
|
# Qdrant
|
||||||
|
QDRANT_URL=http://qdrant:6333
|
||||||
|
QDRANT_COLLECTION=chrysopedia
|
||||||
|
|
||||||
|
# Application
|
||||||
|
APP_ENV=production
|
||||||
|
APP_LOG_LEVEL=info
|
||||||
|
APP_SECRET_KEY=changeme-generate-a-real-secret
|
||||||
|
|
||||||
|
# File storage paths (inside container)
|
||||||
|
TRANSCRIPT_STORAGE_PATH=/data/transcripts
|
||||||
|
VIDEO_METADATA_PATH=/data/video_meta
|
||||||
|
|
||||||
|
# Review mode toggle
|
||||||
|
REVIEW_MODE=true
|
||||||
27
.gitignore
vendored
27
.gitignore
vendored
|
|
@ -4,3 +4,30 @@
|
||||||
.gsd/gsd.db-wal
|
.gsd/gsd.db-wal
|
||||||
.gsd/event-log.jsonl
|
.gsd/event-log.jsonl
|
||||||
.gsd/state-manifest.json
|
.gsd/state-manifest.json
|
||||||
|
|
||||||
|
# ── GSD baseline (auto-generated) ──
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.code-workspace
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
node_modules/
|
||||||
|
.next/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
target/
|
||||||
|
vendor/
|
||||||
|
*.log
|
||||||
|
coverage/
|
||||||
|
.cache/
|
||||||
|
tmp/
|
||||||
|
|
|
||||||
28
backend/main.py
Normal file
28
backend/main.py
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
"""Chrysopedia API — Knowledge extraction and retrieval system."""
|
||||||
|
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
|
app = FastAPI(
|
||||||
|
title="Chrysopedia API",
|
||||||
|
description="Knowledge extraction and retrieval for music production content",
|
||||||
|
version="0.1.0",
|
||||||
|
)
|
||||||
|
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/health")
|
||||||
|
async def health_check():
|
||||||
|
return {"status": "ok", "service": "chrysopedia-api"}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/v1/health")
|
||||||
|
async def api_health():
|
||||||
|
return {"status": "ok", "version": "0.1.0"}
|
||||||
11
backend/requirements.txt
Normal file
11
backend/requirements.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fastapi>=0.115.0,<1.0
|
||||||
|
uvicorn[standard]>=0.32.0,<1.0
|
||||||
|
sqlalchemy[asyncio]>=2.0,<3.0
|
||||||
|
asyncpg>=0.30.0,<1.0
|
||||||
|
alembic>=1.14.0,<2.0
|
||||||
|
pydantic>=2.0,<3.0
|
||||||
|
pydantic-settings>=2.0,<3.0
|
||||||
|
celery[redis]>=5.4.0,<6.0
|
||||||
|
redis>=5.0,<6.0
|
||||||
|
python-dotenv>=1.0,<2.0
|
||||||
|
httpx>=0.27.0,<1.0
|
||||||
42
config/canonical_tags.yaml
Normal file
42
config/canonical_tags.yaml
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Canonical tags — 6 top-level production categories
|
||||||
|
# Sub-topics grow organically during pipeline extraction
|
||||||
|
categories:
|
||||||
|
- name: Sound design
|
||||||
|
description: Creating and shaping sounds from scratch or samples
|
||||||
|
sub_topics: [bass, drums, kick, snare, hi-hat, percussion, pads, leads, fx, foley, vocals, textures]
|
||||||
|
|
||||||
|
- name: Mixing
|
||||||
|
description: Balancing, processing, and spatializing elements
|
||||||
|
sub_topics: [eq, compression, bus processing, reverb, delay, stereo imaging, gain staging, automation]
|
||||||
|
|
||||||
|
- name: Synthesis
|
||||||
|
description: Methods of generating sound
|
||||||
|
sub_topics: [fm, wavetable, granular, additive, subtractive, modular, physical modeling]
|
||||||
|
|
||||||
|
- name: Arrangement
|
||||||
|
description: Structuring a track from intro to outro
|
||||||
|
sub_topics: [song structure, transitions, tension, energy flow, breakdowns, drops]
|
||||||
|
|
||||||
|
- name: Workflow
|
||||||
|
description: Creative process, session management, productivity
|
||||||
|
sub_topics: [daw setup, templates, creative process, collaboration, file management, resampling]
|
||||||
|
|
||||||
|
- name: Mastering
|
||||||
|
description: Final stage processing for release
|
||||||
|
sub_topics: [limiting, stereo width, loudness, format delivery, referencing]
|
||||||
|
|
||||||
|
# Genre taxonomy (assigned to Creators, not techniques)
|
||||||
|
genres:
|
||||||
|
- Bass music
|
||||||
|
- Drum & bass
|
||||||
|
- Dubstep
|
||||||
|
- Halftime
|
||||||
|
- House
|
||||||
|
- Techno
|
||||||
|
- IDM
|
||||||
|
- Glitch
|
||||||
|
- Downtempo
|
||||||
|
- Neuro
|
||||||
|
- Ambient
|
||||||
|
- Experimental
|
||||||
|
- Cinematic
|
||||||
113
docker-compose.yml
Normal file
113
docker-compose.yml
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
# Chrysopedia — Docker Compose
|
||||||
|
# XPLTD convention: xpltd_chrysopedia project, bind mounts, dedicated bridge
|
||||||
|
name: xpltd_chrysopedia
|
||||||
|
|
||||||
|
services:
|
||||||
|
# ── PostgreSQL 16 ──
|
||||||
|
chrysopedia-db:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: chrysopedia-db
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: ${POSTGRES_USER:-chrysopedia}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD required}
|
||||||
|
POSTGRES_DB: ${POSTGRES_DB:-chrysopedia}
|
||||||
|
volumes:
|
||||||
|
- /vmPool/r/services/chrysopedia_db:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:5433:5432"
|
||||||
|
networks:
|
||||||
|
- chrysopedia
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-chrysopedia}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
# ── Redis (Celery broker) ──
|
||||||
|
chrysopedia-redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: chrysopedia-redis
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /vmPool/r/services/chrysopedia_redis:/data
|
||||||
|
networks:
|
||||||
|
- chrysopedia
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
# ── FastAPI application ──
|
||||||
|
chrysopedia-api:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/Dockerfile.api
|
||||||
|
container_name: chrysopedia-api
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-chrysopedia}:${POSTGRES_PASSWORD}@chrysopedia-db:5432/${POSTGRES_DB:-chrysopedia}
|
||||||
|
REDIS_URL: redis://chrysopedia-redis:6379/0
|
||||||
|
volumes:
|
||||||
|
- ./backend:/app
|
||||||
|
- /vmPool/r/services/chrysopedia_data:/data
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8000:8000"
|
||||||
|
depends_on:
|
||||||
|
chrysopedia-db:
|
||||||
|
condition: service_healthy
|
||||||
|
chrysopedia-redis:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- chrysopedia
|
||||||
|
|
||||||
|
# ── Celery worker (pipeline stages 2-5) ──
|
||||||
|
chrysopedia-worker:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/Dockerfile.api
|
||||||
|
container_name: chrysopedia-worker
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file:
|
||||||
|
- path: .env
|
||||||
|
required: false
|
||||||
|
environment:
|
||||||
|
DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-chrysopedia}:${POSTGRES_PASSWORD}@chrysopedia-db:5432/${POSTGRES_DB:-chrysopedia}
|
||||||
|
REDIS_URL: redis://chrysopedia-redis:6379/0
|
||||||
|
command: ["celery", "-A", "worker", "worker", "--loglevel=info"]
|
||||||
|
volumes:
|
||||||
|
- ./backend:/app
|
||||||
|
- /vmPool/r/services/chrysopedia_data:/data
|
||||||
|
- ./prompts:/prompts:ro
|
||||||
|
depends_on:
|
||||||
|
chrysopedia-db:
|
||||||
|
condition: service_healthy
|
||||||
|
chrysopedia-redis:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- chrysopedia
|
||||||
|
|
||||||
|
# ── React web UI (nginx) ──
|
||||||
|
chrysopedia-web:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/Dockerfile.web
|
||||||
|
container_name: chrysopedia-web
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:3000:80"
|
||||||
|
depends_on:
|
||||||
|
- chrysopedia-api
|
||||||
|
networks:
|
||||||
|
- chrysopedia
|
||||||
|
|
||||||
|
networks:
|
||||||
|
chrysopedia:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: 172.24.0.0/24
|
||||||
19
docker/Dockerfile.api
Normal file
19
docker/Dockerfile.api
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
FROM python:3.12-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# System deps
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
gcc libpq-dev \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Python deps (cached layer)
|
||||||
|
COPY backend/requirements.txt /app/requirements.txt
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Application code
|
||||||
|
COPY backend/ /app/
|
||||||
|
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
16
docker/Dockerfile.web
Normal file
16
docker/Dockerfile.web
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
FROM node:22-alpine AS build
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY frontend/package*.json ./
|
||||||
|
RUN npm ci --ignore-scripts
|
||||||
|
COPY frontend/ .
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
FROM nginx:1.27-alpine
|
||||||
|
|
||||||
|
COPY --from=build /app/dist /usr/share/nginx/html
|
||||||
|
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
24
docker/nginx.conf
Normal file
24
docker/nginx.conf
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# SPA fallback
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# API proxy
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://chrysopedia-api:8000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /health {
|
||||||
|
proxy_pass http://chrysopedia-api:8000;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
frontend/package.json
Normal file
10
frontend/package.json
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"name": "chrysopedia-web",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.1.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "echo 'placeholder — install a framework first'",
|
||||||
|
"build": "echo 'placeholder build' && mkdir -p dist && echo '<!DOCTYPE html><html><head><title>Chrysopedia</title></head><body><h1>Chrysopedia</h1><p>Web UI placeholder</p></body></html>' > dist/index.html"
|
||||||
|
}
|
||||||
|
}
|
||||||
2
prompts/README.md
Normal file
2
prompts/README.md
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Prompt templates for LLM pipeline stages
|
||||||
|
# These files are bind-mounted read-only into the worker container.
|
||||||
3
whisper/README.md
Normal file
3
whisper/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Chrysopedia — Whisper Transcription
|
||||||
|
|
||||||
|
Desktop transcription script. See `transcribe.py` for usage.
|
||||||
Loading…
Add table
Reference in a new issue