# === Discovery Config ===
# Service which recommends songs (only 'listenbrainz' is supported)
# DISCOVERY_SERVICE=listenbrainz
# Your ListenBrainz username
LISTENBRAINZ_USER=####
# 'playlist' to fetch weekly playlist (50 songs), 'api' for fewer songs (good for testing) (default: playlist)
LISTENBRAINZ_DISCOVERY=playlist
# === Music System Configuration ===
# Music system you use: emby, jellyfin, mpd, plex or subsonic
EXPLO_SYSTEM=subsonic
# Address of your media system (e.g. http://127.0.0.1:4533)
SYSTEM_URL=http://navidrome:4533
# Username with access to system (required for all except mpd)
SYSTEM_USERNAME=####
# Password for the user (required for subsonic, recommended for plex)
SYSTEM_PASSWORD=####
# Optional admin username for systems like Navidrome/Subsonic (used only for triggering library scans)
# ADMIN_SYSTEM_USERNAME=
# Optional admin password for systems like Navidrome/Subsonic (used only for triggering library scans)
# ADMIN_SYSTEM_PASSWORD=
# API Key from your media system (required for emby and jellyfin, optional for plex)
API_KEY=
# Name of the music library in your system (emby, jellyfin, plex)
LIBRARY_NAME=
# Mark playlist as public (subsonic)
# PUBLIC_PLAYLIST=false
# === Downloader Configuration ===
# Directory to store downloaded tracks. It's recommended to make a separate directory (under the music library) for Explo
# PS! This is only needed when running the binary version, in docker it's set through volume mapping
# DOWNLOAD_DIR=/path/to/musiclibrary/explo/
# Download/move tracks to a subdirectory named after the playlist
# USE_SUBDIRECTORY=true
# Keep original file permissions when moving files (set to false on Synology devices)
# KEEP_PERMISSIONS=true
# Comma-separated list (no spaces) of download services, in priority order (default: youtube)
DOWNLOAD_SERVICES=slskd
# Directory for writing .m3u playlists (required only for MPD)
# PLAYLIST_DIR=/path/to/playlist/folder/
# === YouTube Configuration ===
# YouTube Data API key (required if using youtube)
#YOUTUBE_API_KEY=
# Custom file extension for tracks (e.g mp3) (default: opus)
# TRACK_EXTENSION=opus
# Custom path to ffmpeg binary (default: defined in $PATH)
# FFMPEG_PATH=
# Custom path to yt-dlp binary (default: defined in $PATH)
# YTDLP_PATH=
# Path to (optional) cookies file (default: ./cookies.txt) (in docker this is set through volume mapping)
# COOKIES_PATH=./cookies.txt
# Comma-separated (without spaces) keywords to exclude from YouTube results (default: live,remix,instrumental,extended,clean,acapella)
# FILTER_LIST=live,remix,instrumental,extended
# === Slskd Configuration ===
# Slskd instance address (requires running instance)
SLSKD_URL=http://gluetun:5030
# Slskd API key
SLSKD_API_KEY=####
# Whether to move downloads under the DOWNLOAD_DIR or not (default: false)
MIGRATE_DOWNLOADS=true
# Rename migrated track in {artist}-{title} format
RENAME_TRACK=true
# Directory where slskd downloads tracks (default: /slskd/)
# PS! This is only needed on the binary version, in docker it's set through volume mapping
# SLSKD_DIR=/slskd/
# Number of times to check search status before skipping the track (default: 5)
# SLSKD_RETRY=5
# Number of download attempts for a track (default: 3)
# SLSKD_DL_ATTEMPTS=3
## Slskd Filtering
# Comma-separated (without spaces) file extensions to download from (default: flac,mp3)
EXTENSIONS=flac
# Minimal Bit Depth (default: 8)
# MIN_BIT_DEPTH=8
# Minimal Bitrate (default: 256)
# MIN_BITRATE=256
# Comma-separated (without spaces) keywords to avoid, when filtering slskd results (default: live,remix,instrumental,extended,clean,acapella)
FILTER_LIST=live,remix,instrumental,extended,clean,acapella
# === Metadata / Formatting ===
# Set to true to merge featured artists into title (recommended), false appends them to artist field (default: true)
# SINGLE_ARTIST=true
# Playlist name format: week (Weekly-Exploration-2026-Week5) or date (Weekly-Exploration-2026-01-31)
# PLAYLISTNAME_FORMAT=week
# === Notifications ===
## Discord
# Application's (bot) token
# DISCORD_BOT_TOKEN=
# Channel ID where to send notifications (supports multiple IDs, use comma (without spaces) to separate them)
# DISCORD_CHANNEL_ID=
## HTTP
# HTTP URL to send POST requests to (supports multiple URLs, use comma (without spaces) to separate them)
# HTTP_RECEIVER=
## Matrix
# User ID for Matrix
# MATRIX_USERID=
# Room ID to send notifications in
# MATRIX_ROOMID=
# Homeserver URL that the room is created in
# MATRIX_HOMESERVER_URL=
# Users Access token
# MATRIX_ACCESSTOKEN=
# === Misc ===
# Minutes to sleep between library scans (default: 2)
# SLEEP=2
# Set the log level (DEBUG, INFO, WARN, ERROR) (default: INFO)
LOG_LEVEL=DEBUG
# Set a custom HTTP timeout for music servers (in seconds) (default: 10)
# CLIENT_HTTP_TIMEOUT=10
I've been trying to get this to work automatically for weeks now but I can just never get it to work. I'm worried I'm possibly just stupid and misunderstanding how explo is supposed to work. My setup is the following:
I have slskd running, downloading to a folder that is outside of my music library. I'd like explo to move the files to the "explo" folder within my library after downloading from slskd. Initially I thought this was the default behavior, but eventually I saw there's a config switch for "migrating downloads", which I assumed was the problem, but turning that on didn't help either so now I'm writing this.
The current behavior is that it will download all songs, but then it just won't touch or move them. In the beginning, on my first try, it actually created to target folder, but I think it messed up because I wrongly set the user/group id in the docker-compose file. These are the logs and relevant compose services:
Explo Logs
docker-compose
.env