f74fd5ab88
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>
62 lines
2.1 KiB
YAML
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:
|