# Example slskr app config. Environment variables override these values. # Disable the web UI and browser-session login while retaining API routes. headless = false [flags] # Suppress the target-compatible startup banner. no_logo = false # Complete configuration bootstrap, then exit successfully without starting # the hosted application or binding HTTP. no_start = false # Skip the target-specific startup release check. no_version_check = false # Preserve the frozen restart-only experimental marker. Neither target uses # this legacy flag to activate feature-specific APIs. experimental = false # Make user-supplied search/share/blacklist regular expressions case-sensitive. # This is restart-bound in both frozen targets. case_sensitive_reg_ex = false # Skip all startup share initialization. If both flags are true, this wins. no_share_scan = false # Bypass a valid persisted share cache and scan the filesystem at startup. force_share_scan = false [app] http_bind = "127.0.0.1:5030" state_dir = "/var/lib/slskr" auto_connect = false reconnect = true reconnect_seconds = 30 ping_seconds = 300 # Logging levels: trace, debug, info, warn, error. # Can also be overridden with SLSKR_LOG_LEVEL or RUST_LOG. log_level = "info" [network] server_address = "server.slsknet.org:2242" listen_port = 2234 # Prefer the Web UI "OS credential store" option for desktop/user installs. # For Linux system services, prefer credential_store = "systemd" with # LoadCredential= or LoadCredentialEncrypted= in the unit. systemd mode is # read-only at runtime; update unit credentials and restart the service. # Alternatives: set credential_store = "memory" for runtime-only entry, # credential_store = "file" for a restricted local fallback, or keep using # explicit username/password from env/config for container secret managers. # credential_store = "os" # credential_file = "/var/lib/slskr/soulseek-credentials.json" # username = "user" # password = "pass" [network.obfuscation] enabled = true mode = "compatibility" # compatibility tries regular first; prefer tries obfuscated first prefer_outbound = true # effective only in prefer mode [listeners] regular_bind = "0.0.0.0:2234" advertised_port = 2234 # Native/current type-1 obfuscation shares the regular peer listener. Keep a # separate bind/advertised port only when running a frozen compatibility # profile; native/current rejects a different endpoint. # obfuscated_bind = "0.0.0.0:2235" # obfuscated_advertised_port = 2235 # Current native defaults share the Soulseek TCP listener with the TLS 1.3 # mesh-service/private-gateway listener. A different overlay bind is rejected # in native/current mode. Frozen compatibility profiles retain old behavior. # overlay_bind = "0.0.0.0:50305" [dht] # Native/current defaults enable DHT and share the peer port number across # peer TCP and DHT/mesh/QUIC UDP. This example sets that number to 2234 above; # without an override, the peer port defaults to 50300. # Port 0 is accepted only when DHT is disabled. # enabled = true # port = 0 [mesh] # Native capability messages advertise an overlay port but not the TLS # certificate hash or HTTP range URL. Pin those values explicitly for peers you # operate or have verified out of band. Environment equivalent: # SLSKR_TRUSTED_MESH_PEERS='[{"peerId":"...","username":"...","overlayEndpoint":"203.0.113.10:50305","certificateSha256":"...","rangeEndpoint":"https://mesh.example/content/{sha256}/{size}/{recordingId}"}]' # [[mesh.trusted_peers]] # peer_id = "lower-case-peer-id" # username = "soulseek-user" # overlay_endpoint = "203.0.113.10:50305" # certificate_sha256 = "64-hex-digit-sha256-certificate-fingerprint" # Optional URL templates support {sha256}, {size}, and {recordingId}. # range_endpoint = "https://mesh.example/content/{sha256}/{size}/{recordingId}" [profile] user_info_description = "slskr daemon" [blacklist] enabled = false # file = "/etc/slskr/blacklist.txt" [feature] # Runtime profile defaults differ: false for legacy and true for native. swagger = true [metrics] enabled = false url = "/metrics" [metrics.authentication] disabled = false username = "slskr" # No built-in password is used. Set this whenever metrics are enabled with # authentication; use a secret manager or SLSKD_METRICS_PASSWORD in production. password = "replace-with-a-secret" [timeouts] peer_response_seconds = 5 [podcore.join] # off matches the upstream compatibility default; warn accepts unsigned/legacy # requests but strictly verifies any ed25519: signature supplied; enforce also # requires a fresh timestamp and one-use nonce. Sign the compact JSON array # [1,"join-request",podId,peerId,role,timestamp,message,nonce]. signature_mode = "off" [podcore.gold_star_club] # Native/current slskR launches default to false (opt in with true). An # explicitly selected frozen native profile defaults to true for # parity; set this to false there to opt out. The environment variable # SLSKR_POD_GOLD_STAR_CLUB_AUTOJOIN overrides this value. autojoin = false [shares] dirs = ["/srv/slskr/shares/music"] # Regular expressions match original local directory and file paths. filters = ["\\.ini$", "Thumbs\\.db$", "\\.DS_Store$"] follow_symlinks = false include_hidden = false scan_max_files = 250000 # Emit share-index.tsv for compatibility/debug inspection. SQLite share_files is # the durable share index when [persistence].enabled = true. cache_tsv_enabled = true # fixture = "Virtual/Example.flac=12345" [filters.search] # Drop incoming Soulseek search requests matching any expression. request = ["^.{1,2}$"] [transfers] history_limit = 500 # Combined cap across active uploads and downloads; directional slot limits # below remain the normal admission limits. max_active = 520 allow_inbound = true allow_outbound = true # completed_path_template = "{uploader}/{remote_parent}/{request_name}" [transfers.upload] slots = 20 [transfers.download] slots = 500 [transfers.groups.blacklisted] # The native options API projects this under `groups.blacklisted`, while the # legacy profile projects it under `transfers.groups.blacklisted`. Controller # YAML accepts the documented `transfers.groups` runtime placement for both # profiles; native also accepts top-level `groups` and gives it precedence. members = [] patterns = [] cidrs = [] [transfers.auto_retry] enabled = true retry_delay_seconds = 1800 check_interval_seconds = 300 max_attempts = 5 # 0 means unlimited for the process lifetime max_files_per_cycle = 10 max_files_per_peer_per_cycle = 1 peer_cooldown_seconds = 900 alternate_sources_enabled = true max_alternate_source_searches_per_cycle = 1 alternate_source_size_tolerance_percent = 5 [transfers.rescue] # Detect queued, low-throughput, and stalled audio attempts. When an alternate # is cached, atomically swap sources; otherwise issue one bounded global search. enabled = true max_queue_time_seconds = 1800 min_throughput_kbps = 10 min_duration_seconds = 300 stalled_timeout_seconds = 120 check_interval_seconds = 45 retry_cooldown_seconds = 1800 max_files_per_cycle = 2 alternate_source_size_tolerance_percent = 5 [compatibility] # Selects the slskr controller runtime profile. `native` is the normal daemon # profile; `legacy` is used only by external differential harnesses. # Environment equivalent: # SLSKR_CONTROLLER_PROFILE=legacy profile = "native" # Remote option overlays and configuration-file reads/writes are forbidden # unless explicitly enabled. remote_configuration = false # Frozen upstream aliases DEBUG and NO_CONFIG_WATCH are also accepted. debug = false no_config_watch = false [auth] # Loopback-only binds default to no API auth unless api_token is configured. # Non-loopback binds require an API token unless auth is explicitly disabled. # There is no compatibility fallback password. Configure SLSKD_USERNAME and # SLSKD_PASSWORD (or the corresponding config values) to enable browser login. disabled = false username = "replace-with-username" password = "replace-with-a-random-password" api_token = "replace-with-a-random-token" # Optional distinct least-privilege credentials. Never reuse a token value # across roles. read_write_token = "replace-with-a-distinct-read-write-token" read_only_token = "replace-with-a-distinct-read-only-token" nowplaying_token = "replace-with-a-distinct-nowplaying-token" cookie_auth_enabled = false rate_limit_anonymous = 1000 rate_limit_authenticated = 5000 # Trust forwarded client IP headers only from these proxy CIDRs. trusted_proxy_cidrs = ["127.0.0.1/32"] [persistence] enabled = false [integrations.spotify] # Spotify is the only current third-party surface here with a real OAuth clickthrough. # Configure a Spotify app client ID and redirect URI, then the WebUI can open the # returned authorization_url from /api/integrations/spotify/authorize. enabled = false # client_id = "spotify-app-client-id" # client_secret = "optional-server-side-secret" # redirect_uri = "http://127.0.0.1:5030/api/integrations/spotify/callback" market = "US" scopes = "playlist-read-private playlist-read-collaborative user-library-read" [integrations.lidarr] # Lidarr does not provide OAuth; closest one-click UX is URL/API-key setup plus # a Test/Sync button in the WebUI. enabled = false # url = "http://127.0.0.1:8686" # api_key = "lidarr-api-key" timeout_seconds = 20 [integrations.bridge] enabled = false host = "localhost" port = 3000 [integrations.external_visualizer] # Optional local command launched by the daemon. Launching is disabled unless # launch_enabled is explicitly set. # command = "projectm" launch_enabled = false