skaldsong: scaffold compose stack + deploy playbook for ana-docker
Registry-pull pattern matching Worldtree: CI on vh/skaldsong builds and
pushes gitea.phasefinal.com/vh/skaldsong:<sha>, this playbook pulls +
recreates. SHA-pin only per current preference; no :latest moving-tag
advance yet (revisit once /health exercises Worldtree + Kokoro reach).
Host port 8300 (host) → 8000 (container). Persistent state under
/opt/docker/conf/skaldsong/{db,runs}.
Bifrost endpoint URL 10.250.50.70:8300 will need a paired
BIFROST_CLIENT_ALLOWED_HOSTS update on corviduo-dev Worldtree at first
deploy.
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
# skaldsong stack — single FastAPI + SPA container.
|
||||
#
|
||||
# Skaldsong is the wizard + reader surface that talks to Worldtree as a
|
||||
# Bifrost consumer. One process serves both the SvelteKit-style SPA
|
||||
# (static, baked into the image) and the wizard backend (FastAPI),
|
||||
# plus the Bifrost endpoint Worldtree calls back to.
|
||||
#
|
||||
# Image is built + pushed by vh/skaldsong's `.gitea/workflows/deploy.yaml`
|
||||
# to gitea.phasefinal.com/vh/skaldsong, then pulled here. Workflow
|
||||
# passes the triggering commit SHA via `--var ref=...` to elway, which
|
||||
# substitutes it into ${SKALDSONG_IMAGE} for this compose. SHA-pinned
|
||||
# only by current preference — no :latest moving-tag advance (re-evaluate
|
||||
# once the /health endpoint exercises Worldtree + Kokoro reachability).
|
||||
#
|
||||
# Internal tooling — accessed directly on host:port over the LAN, does
|
||||
# NOT traverse Traefik. State persists under /opt/docker/conf/skaldsong/
|
||||
# {db,runs} on the host; db/ holds skaldsong-ui.db (SQLite, wizard state
|
||||
# + story rows), runs/ holds per-story generation pipeline artifacts
|
||||
# (spec, state, output, logs, manuscripts).
|
||||
#
|
||||
# Per skaldsong's INV-006: process restart marks any 'running' generation
|
||||
# rows 'partial' and never auto-resumes — deploy mid-run is safe; in-flight
|
||||
# work looks to the SPA like a power outage.
|
||||
#
|
||||
# All tunables live in .env — edit that, not this file.
|
||||
|
||||
services:
|
||||
skaldsong-host:
|
||||
image: ${SKALDSONG_IMAGE}
|
||||
container_name: skaldsong
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${SKALDSONG_BIND:-0.0.0.0}:${SKALDSONG_PORT}:8000"
|
||||
environment: &skaldsong-env
|
||||
# App always listens on 8000 internally; host port is the only knob.
|
||||
|
||||
# Worldtree integration — JWT key is the shared-secret Bearer per
|
||||
# Worldtree's HS256 path (same value as Worldtree's own
|
||||
# WORLDTREE_SKALDSONG_USER_KEY). NEVER commit; .env on the server
|
||||
# holds the real value.
|
||||
SKALDSONG_BIFROST_JWT_KEY: "${SKALDSONG_BIFROST_JWT_KEY:-}"
|
||||
|
||||
# URL Worldtree uses to call BACK to skaldsong's Bifrost endpoint
|
||||
# at tool-dispatch time. This is skaldsong's host-side reachable
|
||||
# URL from corviduo-dev's perspective — must match Worldtree's
|
||||
# BIFROST_CLIENT_ALLOWED_HOSTS entry. Coordinated allowlist update
|
||||
# required if host:port changes.
|
||||
SKALDSONG_HOST_BIFROST_ENDPOINT_URL: "${SKALDSONG_HOST_BIFROST_ENDPOINT_URL:-}"
|
||||
|
||||
# URL skaldsong uses to call Worldtree's conversation API. From
|
||||
# ana-docker, this is corviduo-dev's IP:port LAN-direct.
|
||||
SKALDSONG_WORLDTREE_API_URL: "${SKALDSONG_WORLDTREE_API_URL:-http://10.250.50.152:8080}"
|
||||
|
||||
# CORS for the SPA. Comma-separated origins; include both the
|
||||
# public hostname and any dev origins still in rotation.
|
||||
SKALDSONG_HOST_CORS_ORIGINS: "${SKALDSONG_HOST_CORS_ORIGINS:-}"
|
||||
|
||||
# TTS — Kokoro on irv-ml1, reached over WireGuard via ana-wg from
|
||||
# ana-docker. Same URL works fleet-wide.
|
||||
SKALDSONG_TTS_ENGINE: "${SKALDSONG_TTS_ENGINE:-kokoro}"
|
||||
SKALDSONG_TTS_BASE_URL: "${SKALDSONG_TTS_BASE_URL:-http://10.100.79.3:8193}"
|
||||
|
||||
# SPA static assets — baked into the image at /app/web/dist by the
|
||||
# Dockerfile's web-builder stage.
|
||||
SKALDSONG_HOST_STATIC_ASSETS_PATH: /app/web/dist
|
||||
|
||||
# Persistent state paths inside the container. The db/ parent
|
||||
# dir is the bind-mount target (not the file itself) so SQLite
|
||||
# can write its WAL + SHM siblings.
|
||||
SKALDSONG_DB_PATH: /app/state/db/skaldsong-ui.db
|
||||
SKALDSONG_RUNS_DIR: /app/state/runs
|
||||
volumes:
|
||||
# db/ and runs/ are separate bind-mounts so runs/ can later move to
|
||||
# a bigger volume without touching DB state.
|
||||
- ${SKALDSONG_DB_DIR}:/app/state/db
|
||||
- ${SKALDSONG_RUNS_DIR_HOST}:/app/state/runs
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "python -c 'import urllib.request,sys; r=urllib.request.urlopen(\"http://127.0.0.1:8000/health\",timeout=3); sys.exit(0 if r.status==200 else 1)' || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
labels:
|
||||
- homepage.group=AI Systems
|
||||
- homepage.name=Skaldsong
|
||||
- homepage.icon=mdi-book-edit-outline
|
||||
- homepage.description=Wizard + reader surface for multi-agent storytelling (Bifrost consumer of Worldtree)
|
||||
- homepage.href=http://10.250.50.70:${SKALDSONG_PORT}
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: skaldsong_default
|
||||
Reference in New Issue
Block a user