asset-engine + irv-ml1: scaffold orchestrator wiring
Three changes prepping infra for asset_engine's orchestration feature
(SSH-driven bring-up / bring-down of irv-ml1 inference services with
per-device VRAM gating, contract in vh/asset-engine commit 5a36f8c):
1. asset-engine compose + .env.example + playbook gain a read-only
bind-mount for /app/runtime/ssh — the dedicated ed25519 keypair
(generated on ana-docker, not in the repo) plus a pinned known_hosts
for irv-ml1's host fingerprint. Env vars SSH_KEY_PATH and
SSH_KNOWN_HOSTS are exposed for the app to consume.
2. docs/asset-engine/services.yaml gains a `lifecycle: { stack, vram_gb,
gpu_device_id }` block on each of 12 orchestratable irv-ml1 services
(kokoro, chatterbox, index-tts, qwen3-tts, cosyvoice, fish-s2,
kyutai-tts, vibevoice, voxtral, parakeet, stable-audio-open, ace-step).
VRAM numbers are estimates from model footprint at fp16 — tune from
real nvidia-smi measurements once the gate is live. comfyui and
kokoro-captioned are deliberately excluded (variable-VRAM and
shared-container respectively).
3. servers/irv-ml1/README.md docker-stacks table now lists all 13
inference stacks (was only dockge + agents + comfyui) with port +
GPU pinning columns.
Pubkey deployed to ~lkraven/.ssh/authorized_keys on irv-ml1;
end-to-end SSH from ana-docker → irv-ml1 verified with strict
host-key checking.
This commit is contained in:
@@ -28,6 +28,10 @@ services:
|
|||||||
category: tts
|
category: tts
|
||||||
version: 2
|
version: 2
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: kokoro
|
||||||
|
vram_gb: 2
|
||||||
|
gpu_device_id: null
|
||||||
endpoint: http://10.100.79.3:8193/v1/audio/speech
|
endpoint: http://10.100.79.3:8193/v1/audio/speech
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
@@ -201,6 +205,10 @@ services:
|
|||||||
version: 1
|
version: 1
|
||||||
status: down
|
status: down
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: chatterbox
|
||||||
|
vram_gb: 4
|
||||||
|
gpu_device_id: 0
|
||||||
endpoint: http://10.100.79.3:8196/v1/audio/speech
|
endpoint: http://10.100.79.3:8196/v1/audio/speech
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
@@ -261,6 +269,10 @@ services:
|
|||||||
version: 1
|
version: 1
|
||||||
status: down
|
status: down
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: index-tts
|
||||||
|
vram_gb: 6
|
||||||
|
gpu_device_id: null
|
||||||
endpoint: http://10.100.79.3:8192/v1/audio/speech
|
endpoint: http://10.100.79.3:8192/v1/audio/speech
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
@@ -337,6 +349,10 @@ services:
|
|||||||
version: 1
|
version: 1
|
||||||
status: down
|
status: down
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: qwen3-tts
|
||||||
|
vram_gb: 16
|
||||||
|
gpu_device_id: null
|
||||||
endpoint: http://10.100.79.3:8191/v1/audio/speech
|
endpoint: http://10.100.79.3:8191/v1/audio/speech
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
@@ -394,6 +410,10 @@ services:
|
|||||||
version: 1
|
version: 1
|
||||||
status: down
|
status: down
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: cosyvoice
|
||||||
|
vram_gb: 4
|
||||||
|
gpu_device_id: null
|
||||||
endpoint: http://10.100.79.3:8190/v1/audio/speech
|
endpoint: http://10.100.79.3:8190/v1/audio/speech
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
@@ -454,6 +474,10 @@ services:
|
|||||||
category: tts
|
category: tts
|
||||||
version: 1
|
version: 1
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: fish-s2
|
||||||
|
vram_gb: 4
|
||||||
|
gpu_device_id: 1
|
||||||
endpoint: http://10.100.79.3:8195/v1/tts
|
endpoint: http://10.100.79.3:8195/v1/tts
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
@@ -503,6 +527,10 @@ services:
|
|||||||
version: 1
|
version: 1
|
||||||
status: down
|
status: down
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: kyutai-tts
|
||||||
|
vram_gb: 6
|
||||||
|
gpu_device_id: 0
|
||||||
endpoint: http://10.100.79.3:8198/v1/audio/speech
|
endpoint: http://10.100.79.3:8198/v1/audio/speech
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
@@ -552,6 +580,10 @@ services:
|
|||||||
category: tts
|
category: tts
|
||||||
version: 2
|
version: 2
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: vibevoice
|
||||||
|
vram_gb: 20
|
||||||
|
gpu_device_id: 1
|
||||||
endpoint: http://10.100.79.3:8194/v1/audio/speech
|
endpoint: http://10.100.79.3:8194/v1/audio/speech
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
@@ -636,6 +668,10 @@ services:
|
|||||||
version: 1
|
version: 1
|
||||||
status: down
|
status: down
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: voxtral
|
||||||
|
vram_gb: 12
|
||||||
|
gpu_device_id: 1
|
||||||
endpoint: http://10.100.79.3:8197/v1/audio/speech
|
endpoint: http://10.100.79.3:8197/v1/audio/speech
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
@@ -689,6 +725,10 @@ services:
|
|||||||
category: asr
|
category: asr
|
||||||
version: 1
|
version: 1
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: parakeet
|
||||||
|
vram_gb: 2
|
||||||
|
gpu_device_id: null
|
||||||
endpoint: http://10.100.79.3:8765/transcribe
|
endpoint: http://10.100.79.3:8765/transcribe
|
||||||
method: POST
|
method: POST
|
||||||
content_type: multipart/form-data
|
content_type: multipart/form-data
|
||||||
@@ -724,6 +764,10 @@ services:
|
|||||||
category: sfx
|
category: sfx
|
||||||
version: 1
|
version: 1
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: stable-audio-open
|
||||||
|
vram_gb: 6
|
||||||
|
gpu_device_id: 1
|
||||||
endpoint: http://10.100.79.3:8211/v1/audio/sfx
|
endpoint: http://10.100.79.3:8211/v1/audio/sfx
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
@@ -787,6 +831,10 @@ services:
|
|||||||
category: music
|
category: music
|
||||||
version: 5
|
version: 5
|
||||||
host: irv-ml1
|
host: irv-ml1
|
||||||
|
lifecycle:
|
||||||
|
stack: ace-step
|
||||||
|
vram_gb: 16
|
||||||
|
gpu_device_id: 1
|
||||||
endpoint: http://10.100.79.3:8210/generate
|
endpoint: http://10.100.79.3:8210/generate
|
||||||
method: POST
|
method: POST
|
||||||
content_type: application/json
|
content_type: application/json
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ vars:
|
|||||||
compose_dir: /opt/docker/compose/asset-engine
|
compose_dir: /opt/docker/compose/asset-engine
|
||||||
db_dir: /opt/docker/conf/asset-engine/db
|
db_dir: /opt/docker/conf/asset-engine/db
|
||||||
outputs_dir: /opt/docker/conf/asset-engine/outputs
|
outputs_dir: /opt/docker/conf/asset-engine/outputs
|
||||||
|
ssh_dir: /opt/docker/conf/asset-engine/ssh
|
||||||
host_port: "8200"
|
host_port: "8200"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -90,6 +91,11 @@ steps:
|
|||||||
shell: mkdir -p {{ outputs_dir }}
|
shell: mkdir -p {{ outputs_dir }}
|
||||||
creates: "{{ outputs_dir }}"
|
creates: "{{ outputs_dir }}"
|
||||||
|
|
||||||
|
- name: Ensure SSH key dir exists (parent only — keys themselves are seeded
|
||||||
|
out-of-band on the host so the private key never crosses the network)
|
||||||
|
shell: mkdir -p {{ ssh_dir }} && chmod 700 {{ ssh_dir }}
|
||||||
|
creates: "{{ ssh_dir }}"
|
||||||
|
|
||||||
# ── deploy compose files ────────────────────────────────────────────
|
# ── deploy compose files ────────────────────────────────────────────
|
||||||
- name: Upload compose.yaml
|
- name: Upload compose.yaml
|
||||||
upload:
|
upload:
|
||||||
|
|||||||
@@ -65,12 +65,29 @@ Docker 29.4.1 with `nvidia` and `runc` runtimes. `lkraven` is in the
|
|||||||
`docker` group. `traefik-net` external network exists for stacks that
|
`docker` group. `traefik-net` external network exists for stacks that
|
||||||
need it.
|
need it.
|
||||||
|
|
||||||
| Stack | Port | Role |
|
| Stack | Port | GPU | Role |
|
||||||
|-------|------|------|
|
|-------|------|-----|------|
|
||||||
| dockge | 5001 | Per-host Compose UI |
|
| dockge | 5001 | — | Per-host Compose UI |
|
||||||
| beszel-agent-irv | 45876 | Metrics agent → Beszel hub on ana-docker (token mode through WG) |
|
| beszel-agent-irv | 45876 | — | Metrics agent → Beszel hub on ana-docker (token mode through WG) |
|
||||||
| dozzle-agent-irv | 7007 | Log agent → Dozzle hub on ana-docker |
|
| dozzle-agent-irv | 7007 | — | Log agent → Dozzle hub on ana-docker |
|
||||||
| comfyui | 8188 | ComfyUI (node-based SD/Flux) — runs independently of `/opt/ComfyUI` native install |
|
| comfyui | 8188 | all | ComfyUI (node-based SD/Flux) — runs independently of `/opt/ComfyUI` native install |
|
||||||
|
| kokoro | 8193 | all | Kokoro 82M TTS — lowest-latency English TTS, OpenAI-compatible /v1/audio/speech |
|
||||||
|
| chatterbox | 8196 | 0 (3090) | Chatterbox voice-cloning TTS |
|
||||||
|
| index-tts | 8192 | all | IndexTTS multilingual TTS |
|
||||||
|
| qwen3-tts | 8191 | all | Qwen3-TTS — 7B multilingual TTS |
|
||||||
|
| cosyvoice | 8190 | all | CosyVoice multilingual TTS |
|
||||||
|
| fish-s2 | 8195 | 1 (A6000) | Fish-Speech S2 TTS |
|
||||||
|
| kyutai-tts | 8198 | 0 (3090) | Kyutai TTS |
|
||||||
|
| vibevoice | 8194 | 1 (A6000) | Microsoft VibeVoice TTS |
|
||||||
|
| voxtral | 8197 | 1 (A6000) | Mistral Voxtral ASR |
|
||||||
|
| parakeet | 8765 | all | NVIDIA Parakeet ASR (transcription) |
|
||||||
|
| stable-audio-open | 8211 | 1 (A6000) | Stable Audio Open 1.0 — diffusion SFX/ambience generator |
|
||||||
|
| ace-step | 8210 | 1 (A6000) | ACE-Step 1.5 — Apache-2.0 hybrid diffusion+LLM music generation |
|
||||||
|
|
||||||
|
GPU pinning comes from the compose `NVIDIA_VISIBLE_DEVICES` default;
|
||||||
|
`all` means the model picks at runtime (typically GPU 0). The
|
||||||
|
asset-engine orchestrator (`docs/asset-engine/services.yaml` → per-service
|
||||||
|
`lifecycle:` block) gates start operations on per-device VRAM headroom.
|
||||||
|
|
||||||
Exposed Docker socket on `*:2375` (for the homepage integration hub on
|
Exposed Docker socket on `*:2375` (for the homepage integration hub on
|
||||||
esh-docker-vm, which auto-discovers containers on this host).
|
esh-docker-vm, which auto-discovers containers on this host).
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ ASSET_ENGINE_BIND=0.0.0.0
|
|||||||
ASSET_ENGINE_DB_DIR=/opt/docker/conf/asset-engine/db
|
ASSET_ENGINE_DB_DIR=/opt/docker/conf/asset-engine/db
|
||||||
ASSET_ENGINE_OUTPUTS_DIR=/opt/docker/conf/asset-engine/outputs
|
ASSET_ENGINE_OUTPUTS_DIR=/opt/docker/conf/asset-engine/outputs
|
||||||
|
|
||||||
|
# SSH key dir for orchestrating irv-ml1 services (bring up / down via SSH +
|
||||||
|
# docker compose). Holds id_ed25519 (mode 600) + known_hosts (mode 644)
|
||||||
|
# pre-populated with irv-ml1's pinned ed25519 fingerprint. Generated on the
|
||||||
|
# host directly so the private key never crosses the network. Bind-mounted
|
||||||
|
# read-only into the container at /app/runtime/ssh.
|
||||||
|
ASSET_ENGINE_SSH_DIR=/opt/docker/conf/asset-engine/ssh
|
||||||
|
|
||||||
# Inference target. Default is irv-ml1 over WG. Override if the fleet's
|
# Inference target. Default is irv-ml1 over WG. Override if the fleet's
|
||||||
# inference host moves.
|
# inference host moves.
|
||||||
INFERENCE_HOST=10.100.79.3
|
INFERENCE_HOST=10.100.79.3
|
||||||
|
|||||||
@@ -15,8 +15,9 @@
|
|||||||
#
|
#
|
||||||
# Internal tooling — accessed directly on host:port over the LAN, does
|
# Internal tooling — accessed directly on host:port over the LAN, does
|
||||||
# NOT traverse Traefik. State persists under /opt/docker/conf/asset-engine/
|
# NOT traverse Traefik. State persists under /opt/docker/conf/asset-engine/
|
||||||
# {db,outputs} on the host — separate bind-mounts so outputs/ can move
|
# {db,outputs,ssh} on the host — db/outputs are separate bind-mounts so
|
||||||
# to a bigger volume later without touching DB state.
|
# outputs/ can move to a bigger volume later without touching DB state;
|
||||||
|
# ssh/ holds the dedicated keypair used to orchestrate irv-ml1 services.
|
||||||
#
|
#
|
||||||
# All tunables live in .env — edit that, not this file.
|
# All tunables live in .env — edit that, not this file.
|
||||||
|
|
||||||
@@ -36,9 +37,15 @@ services:
|
|||||||
- OIDC_ISSUER=${OIDC_ISSUER:-}
|
- OIDC_ISSUER=${OIDC_ISSUER:-}
|
||||||
- OIDC_CLIENT_ID=${OIDC_CLIENT_ID:-}
|
- OIDC_CLIENT_ID=${OIDC_CLIENT_ID:-}
|
||||||
- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET:-}
|
- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET:-}
|
||||||
|
# Orchestration SSH paths inside the container.
|
||||||
|
- SSH_KEY_PATH=/app/runtime/ssh/id_ed25519
|
||||||
|
- SSH_KNOWN_HOSTS=/app/runtime/ssh/known_hosts
|
||||||
volumes:
|
volumes:
|
||||||
- ${ASSET_ENGINE_DB_DIR}:/app/runtime/db
|
- ${ASSET_ENGINE_DB_DIR}:/app/runtime/db
|
||||||
- ${ASSET_ENGINE_OUTPUTS_DIR}:/app/runtime/outputs
|
- ${ASSET_ENGINE_OUTPUTS_DIR}:/app/runtime/outputs
|
||||||
|
# Dedicated SSH key for orchestrating irv-ml1 services (up/down).
|
||||||
|
# Read-only; key is generated on the host, never crosses the network.
|
||||||
|
- ${ASSET_ENGINE_SSH_DIR}:/app/runtime/ssh:ro
|
||||||
healthcheck:
|
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"]
|
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
|
interval: 30s
|
||||||
|
|||||||
Reference in New Issue
Block a user