asset-engine: scaffold deploy stack on ana-docker
Mirrors task-board's build-on-host pattern: elway playbook clones vh/asset-engine into /opt/docker/build/, docker build, install compose + seed .env, up -d, verify /health. No registry. Internal-only tool — LAN port 8200 (bind 0.0.0.0) is primary; Traefik labels additionally route asset-engine.phasefinal.com with TLS via the anaprod cert resolver. DB and outputs are separate bind-mounts under /opt/docker/conf/asset-engine/ so outputs/ can move volumes later without touching DB state. INFERENCE_HOST defaults to 10.100.79.3 (irv-ml1 over WG). OIDC env seam is pre-allocated empty for v2.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# asset-engine — control plane over PFI's inference fleet.
|
||||
#
|
||||
# FastAPI + HTMX/Shoelace UI. Reads the catalog at services.yaml (baked
|
||||
# into the image at build time, drift-checked in CI against the copy
|
||||
# at docs/asset-engine/services.yaml in this repo), routes requests to
|
||||
# inference hosts (irv-ml1 over WG by default), persists Assets to a
|
||||
# local SQLite WAL DB, stores generated blobs content-addressed under
|
||||
# runtime/outputs/.
|
||||
#
|
||||
# Image is built on the host from the asset-engine git repo by the
|
||||
# deploy playbook (`playbooks/deploy-asset-engine.yaml`), which clones
|
||||
# into /opt/docker/build/asset-engine and runs `docker build -t
|
||||
# asset-engine:local .` before installing this compose and bringing
|
||||
# it up. No registry.
|
||||
#
|
||||
# State persists under /opt/docker/conf/asset-engine/{db,outputs} on
|
||||
# the host — separate bind-mounts so outputs/ can move to a bigger
|
||||
# volume later without touching DB state.
|
||||
#
|
||||
# All tunables live in .env — edit that, not this file.
|
||||
|
||||
services:
|
||||
asset-engine:
|
||||
image: ${ASSET_ENGINE_IMAGE}
|
||||
container_name: asset-engine
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${ASSET_ENGINE_BIND:-0.0.0.0}:${ASSET_ENGINE_PORT}:8000"
|
||||
environment:
|
||||
# App always listens on 8000 internally; host port is the only knob.
|
||||
- RUNTIME_DIR=/app/runtime
|
||||
- DB_URL=sqlite:////app/runtime/db/asset_engine.db
|
||||
- INFERENCE_HOST=${INFERENCE_HOST:-10.100.79.3}
|
||||
# OIDC seam is empty in v1; populated in v2 when forward-auth lands.
|
||||
- OIDC_ISSUER=${OIDC_ISSUER:-}
|
||||
- OIDC_CLIENT_ID=${OIDC_CLIENT_ID:-}
|
||||
- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET:-}
|
||||
volumes:
|
||||
- ${ASSET_ENGINE_DB_DIR}:/app/runtime/db
|
||||
- ${ASSET_ENGINE_OUTPUTS_DIR}:/app/runtime/outputs
|
||||
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
|
||||
networks:
|
||||
- tnet
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.asset-engine.rule=Host(`asset-engine.phasefinal.com`)
|
||||
- traefik.http.routers.asset-engine.entrypoints=websecure
|
||||
- traefik.http.routers.asset-engine.tls=true
|
||||
- traefik.http.routers.asset-engine.tls.certresolver=anaprod
|
||||
- traefik.http.routers.asset-engine.middlewares=crowdsec@file
|
||||
- traefik.http.services.asset-engine.loadbalancer.server.port=8000
|
||||
- homepage.group=AI Systems
|
||||
- homepage.name=Asset Engine
|
||||
- homepage.icon=mdi-tools
|
||||
- homepage.description=Control plane over the PFI inference fleet
|
||||
- homepage.href=https://asset-engine.phasefinal.com
|
||||
|
||||
networks:
|
||||
tnet:
|
||||
name: traefik-net
|
||||
external: true
|
||||
Reference in New Issue
Block a user