Skip to content

Configuration

djsnake is configured through environment variables. With Docker Compose, put them in a .env file next to docker-compose.yml (copy .env.example); Compose passes the file to the container. Without Docker, the bot loads .env itself. Variables are read once at startup, so restart the bot after changing them.

VariableDefaultMeaning
DISCORD_TOKENnone (required)Bot token. A token file is a fallback.
COMMAND_PREFIX!Prefix for text commands.
MAX_PLAYLIST_SIZE30Tracks loaded from a playlist (YouTube, Spotify, SoundCloud, Bandcamp, Deezer or Apple Music) by default. A longer one asks whether to load these or the whole list.
MAX_PLAYLIST_FULL200Most tracks “Whole playlist” loads (never below MAX_PLAYLIST_SIZE). The room left in the queue (MAX_QUEUE_SIZE, MAX_TRACKS_PER_USER, /limits) also caps it.
MAX_QUEUE_SIZE200Maximum tracks waiting in a server’s queue.
MAX_TRACKS_PER_USER0Maximum tracks one member may have waiting (0 = unlimited). The clip page counts as one member.
MAX_TRACK_MINUTES0Longest single track accepted, in minutes (0 = unlimited).
PLAY_COOLDOWN_SECONDS0Seconds a member must wait between two /play calls (0 = none).
MEDIA_FORMATmax 720p H.264 + m4ayt-dlp format selector. The default is bestvideo[height<=720][vcodec^=avc1]+bestaudio[ext=m4a]/best[height<=720][ext=mp4]/best[height<=720]/best.
TEMP_DIRa fresh temporary directoryWhere downloaded tracks are stored. Files are deleted once played.
POT_BASE_URLhttp://pot-provider:4416URL of the PO token provider. The default matches Docker Compose.
WEB_PORT47823Clip page port, inside the container and on the host.
WEB_BIND127.0.0.1Host IP the web port is published on (Compose only). Use a LAN IP or 0.0.0.0 for a reverse proxy or tunnel.
PUBLIC_BASE_URLempty (http://localhost:WEB_PORT)Public address used in the clip link the bot posts, for example https://dj.example.com.
SESSION_IDLE_HOURS6Hours without activity before a clip page link expires.
IDLE_DISCONNECT_SECONDS300Seconds the bot stays in voice once the queue runs out, before leaving (30 s instead when no human is left in the channel).
AUTOPLAY0Default of the per-session autoplay setting (1, true, on or yes to start with it on). Change it per session with !autoplay or the clip page.
VOTESKIP_PERCENT50Default vote-to-skip threshold, 1 to 100: more than this share of the listeners must vote. Change it per server with /voteskip threshold.
STAY_2470Default of the per-server 24/7 mode for servers that never ran !stay (1, true, on or yes): the bot never leaves voice on its own. A server needs a remembered voice channel to be rejoined after a restart.
LIVE_MAX_HOURS4Hours a live stream (YouTube live, Twitch channel, internet radio) plays before the bot moves on to the next track, so a forgotten stream does not run forever. 0 turns the limit off. See Live streams.
SLASH_SYNC_GUILDemptyServer ID. When set, slash commands are published to that server only, and show up at once (for development). Empty publishes them globally, which Discord can take up to an hour to show.
DATA_DIR/app/dataPersistent data: per-server themes (themes.json), languages (languages.json), volumes (volume.json), vote-skip thresholds (voteskip.json), DJ roles (permissions.json), queue limits (limits.json), 24/7 mode (stay.json), saved playlists (playlists.db), logos (logos/), listening stats (stats.db) and cached lyrics (lyrics/). Compose mounts ./data there.
WEB_CONTROLeveryoneWho gets the clip page’s control link. everyone: the status message shows it next to the view-only link. dj: it shows only the view-only link, and DJs get the control link by DM with !weblink. A server with a DJ role always behaves as dj. See Who controls the music.
WEB_THEMEarcadeDefault clip page theme for servers that never ran !theme: arcade, minimal, night, vinyl, club, terminal, space or cobalt.
LYRICS1Synced lyrics on the clip page, from LRCLIB. 0 turns them off: the bot sends no lookups and the page hides the Lyrics button. See Lyrics.
BOT_LANGUAGEenLanguage of the bot’s messages and of the clip page for servers that never ran !language: en (English), fr (French), es (Spanish) or de (German).
SPOTIFY_CLIENT_ID / SPOTIFY_CLIENT_SECRETemptyOptional Spotify Web API credentials, for playlists over 100 tracks. Both are needed. See Spotify.
YTDLP_COOKIESemptyPath to a Netscape cookies.txt for age-restricted and members-only videos. Copied to a private temp file at startup. Use a throwaway Google account: see Keeping YouTube working.
BACKUP_INTERVAL_HOURS0Hours between automatic backups of DATA_DIR into DATA_DIR/backups/ (0 = off). See Backup and restore.
BACKUP_KEEP7Automatic backups to keep. See Backup and restore.
LASTFM_API_KEY / LASTFM_API_SECRETemptyOptional Last.fm API credentials. Both are needed to turn on scrobbling. See Last.fm.
YTDLP_AUTO_UPDATE1Upgrade yt-dlp on container start (0 to skip). Used by the container entrypoint only.
METRICS0Set to 1 to serve Prometheus metrics on GET /metrics (same port as the clip page). Off, the route answers 404. See Troubleshooting.
SHARD_COUNTautomaticNumber of gateway shards. Empty lets discord.py use the count Discord recommends; set a positive integer to force one. Anything else is ignored with a warning. One process runs every shard. See Architecture.
DJ_SNAKE_TAGlatestImage tag to pull (Compose only), for example 1.0.0.
  • PUBLIC_BASE_URL matters. It is only used to build the link the bot posts in Discord. If it is empty, the link points to http://localhost:47823, which only works on the machine running the bot.
  • MEDIA_FORMAT replaces the old AUDIO_FORMAT variable, which is no longer read. The clip page needs a video stream, so choose a format that includes one.
  • MAX_PLAYLIST_SIZE and MAX_PLAYLIST_FULL apply to Spotify lists too. Without credentials Spotify’s embed page lists at most 100 tracks; the prompt then says the list may be longer.
  • Never commit .env, a token file or any real token.