Deploy slskd (Soulseek client) via its official Docker image
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Paul Provost 7309623b05 Compare env and volumes strictly so removing the share applies
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 15:46:03 -04:00
defaults Make sharing optional: no slskd_shared_dir, no share 2026-10-21 15:34:20 -04:00
meta Initial slskd role, modelled on the lidarr role 2026-10-21 14:29:20 -04:00
tasks Compare env and volumes strictly so removing the share applies 2026-10-21 15:46:03 -04:00
README.md Make sharing optional: no slskd_shared_dir, no share 2026-10-21 15:34:20 -04:00

slskd

Deploy slskd, a Soulseek client with a web UI, via its official slskd/slskd Docker image.

Requirements

  • community.docker collection (needs the python3-docker apt package's bindings - this role installs it).
  • If you share a library (slskd_shared_dir), it must already exist before this role runs - it's owned by whatever manages that share (a NAS mount/autofs/etc.), so the role fails loudly if it's missing rather than sharing an empty decoy directory.
  • A Soulseek account (just pick a username/password - the server creates the account on first login).
  • For other peers to browse and download from you, forward TCP slskd_listen_port (default 50300) on your router to this host.

Role Variables

Variable Default Description
slskd_config_dir ~/local/slskd/app Host directory mounted at /app (slskd.yml, database, logs). Created by this role.
slskd_image slskd/slskd:latest Docker image.
slskd_uid / slskd_gid 1000 User the container runs as (docker --user; not a linuxserver.io image).
slskd_tz Etc/UTC Container timezone.
slskd_http_port 5030 Web UI port.
slskd_listen_port 50300 Soulseek peer listen port, published unchanged on the host.
slskd_shared_dir "" (share nothing) Optional host path shared with the network, mounted read-only at /music. Must already exist.
slskd_downloads_dir "" (required) Completed downloads, mounted at /downloads. Created by this role.
slskd_incomplete_dir "" (required) In-progress downloads, mounted at /incomplete. Created by this role.
slskd_slsk_username / slskd_slsk_password "" (required) Soulseek network account.
slskd_web_username / slskd_web_password "" (required) Web UI login (replaces slskd's slskd/slskd default).

Configuration

Directories, the listen port and all credentials are passed as SLSKD_* environment variables, which take precedence over /app/slskd.yml. Everything else (speed limits, slots, filters, etc.) lives in /app/slskd.yml, editable from the web UI (SLSKD_REMOTE_CONFIGURATION=true) - this role never templates it.

Example Playbook

- hosts: sulaco
  vars:
    ansible_python_interpreter: /usr/bin/python3
  roles:
    - role: slskd
      slskd_downloads_dir: /mnt/disks/storage3/slskd/downloads
      slskd_incomplete_dir: /mnt/disks/storage3/slskd/incomplete
      # slskd_slsk_* / slskd_web_* from a vault

Notes

  • With a share set, slskd doesn't answer HTTP until its first share scan finishes. Over a large network share that can take an hour, so the first run's "Wait for slskd to accept connections" task can time out (2 minutes) while the container is fine - watch docker logs slskd for the scan and re-run once it's done. The scan result is backed up under /app/data, so later restarts load it rather than rescanning.
  • The container task runs with no_log: true, since its env holds the credentials.
  • Uses ansible_python_interpreter: /usr/bin/python3 in the example above for the same reason the lidarr/sonarr roles do: Linuxbrew's Python (if present, earlier in PATH) doesn't have python3-docker's bindings.