Files
Lyra/docker-compose.yml
T
Jonathan f74fd5ab88 fix(worker): retrieve Soulseek downloads from slskd's dir into staging
SlskdClient enqueued the transfer and polled to Completed but never moved any
files into `dest` — slskd saves them to its OWN downloads dir, so staging stayed
empty and every Soulseek job failed "incomplete download". Qobuz/YouTube write
straight into staging and were unaffected.

- SlskdClient._retrieve() moves the finished files out of slskd's downloads dir
  into staging after completion, matching tolerantly by basename and preferring
  a parent-folder + size match (slskd's on-disk layout varies by version).
- download() returns the moved count as track_count so the pipeline's
  completeness check reflects what actually landed; raises loudly if nothing was
  found (misconfigured/unmounted downloads dir).
- Downloads dir resolves slskd.downloadsDir Config > SLSKD_DOWNLOADS_ROOT env >
  /slskd-downloads default; docker-compose mounts ${SLSKD_DOWNLOADS_DIR} there.
- .env.example documents SLSKD_DOWNLOADS_DIR; retrieval unit-tested offline.

slskd runs as an external daemon, so the shared dir must be a host path both
slskd and the worker mount — set once Lyra runs on the slskd host. Not yet
verified live end-to-end (no slskd access from this VM).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 09:59:16 +02:00

62 lines
2.1 KiB
YAML

services:
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
web:
build: ./web
restart: unless-stopped
environment:
DATABASE_URL: ${DATABASE_URL}
LYRA_SECRET_KEY: ${LYRA_SECRET_KEY}
ports:
# host:container — host 8770 avoids the Quill app on 3000 (and Lidarr on 8686)
- "8770:3000"
depends_on:
db:
condition: service_healthy
worker:
build: ./worker
restart: unless-stopped
environment:
DATABASE_URL: ${DATABASE_URL}
LYRA_SECRET_KEY: ${LYRA_SECRET_KEY}
STAGING_ROOT: /staging
SLSKD_DOWNLOADS_ROOT: /slskd-downloads
# Qobuz's CDN also resolves to IPv6, but the container has no IPv6 route
# ("Network is unreachable"); disable IPv6 so downloads use IPv4 only.
sysctls:
- net.ipv6.conf.all.disable_ipv6=1
volumes:
- ${MUSIC_DIR:-./music}:/music
# Per-job download staging on its own volume. Defaults to MUSIC_DIR/.staging (prior
# behavior); set STAGING_DIR to a fast local path when MUSIC_DIR is a network share.
- ${STAGING_DIR:-${MUSIC_DIR:-./music}/.staging}:/staging
# slskd (an EXTERNAL daemon, not in this compose stack) writes finished Soulseek
# downloads into its own directory; the worker moves them out of here into staging.
# Point SLSKD_DOWNLOADS_DIR at slskd's downloads dir on the host (must be the SAME
# path slskd writes to — set it once Lyra runs on the slskd host). Defaults to an
# empty local dir so the mount is always valid; Soulseek delivery only works once
# this points at the real slskd downloads directory.
- ${SLSKD_DOWNLOADS_DIR:-./slskd-downloads}:/slskd-downloads
depends_on:
db:
condition: service_healthy
volumes:
postgres-data: