A reusable Lavalink v4 server starter for Discord music bots, with YouTube, YouTube Music, and optional Spotify support.
Clone it for each project, set your password, and start the audio server with Docker Compose. Connect your own Discord bot using a Lavalink v4 client.
Includes Lavalink 4.2.2, YouTube plugin 1.18.2, and LavaSrc 4.8.3 for Spotify support, alongside SoundCloud, Bandcamp, Twitch, Vimeo, Nico, and HTTP audio sources. Lavalink downloads the plugins on first startup, so startup needs internet access. Spotify is configured but disabled until you add credentials.
| Feature | Included |
|---|---|
| Audio server | Official Lavalink image with a pinned version |
| YouTube and YouTube Music | Video URLs, playlist URLs, and text searches |
| Spotify integration | Metadata loading and YouTube audio matching through LavaSrc |
| More sources | SoundCloud, Bandcamp, Twitch, Vimeo, Nico, and HTTP audio |
| Local configuration | Password, port, heap size, and Spotify credentials through .env |
| Docker operation | Automatic restart and bounded container logs |
| Reuse | Per-project ports, Compose project names, and template repository support |
This repository contains the server configuration. Your Discord bot supplies the commands, queue management, and voice connection events. Spotify audio matching depends on both Spotify metadata access and YouTube playback availability.
| File | Purpose |
|---|---|
application.yml |
Lavalink sources and plugin settings |
compose.yml |
Docker image, environment, networking, and logs |
.env.example |
Settings to copy into your private .env |
.gitignore |
Excludes credentials, downloaded JARs, and runtime files |
.gitattributes |
Consistent text line endings across operating systems |
Install Docker with Compose support. On Windows, start Docker Desktop with Linux containers enabled. Docker includes the Java runtime; a separate Java installation is only needed for the optional native setup.
Clone this repository, or use GitHub's Use this template option to create your own copy:
git clone https://github.com/mrcholer/lavalink.git
cd lavalink-
Copy
.env.exampleto.env:PowerShell:
Copy-Item .env.example .envLinux / macOS:
cp .env.example .env
-
Edit
.envand replaceLAVALINK_SERVER_PASSWORDwith your own password. -
Start the server from this folder:
docker compose up -d docker compose logs -f lavalink
Press Ctrl+C to exit the logs; the server keeps running. Stop it with:
docker compose downEdit .env after copying .env.example:
| Variable | Default in the example | Purpose |
|---|---|---|
LAVALINK_SERVER_PASSWORD |
Placeholder; replace it | Shared password between server and bot |
LAVALINK_BIND_ADDRESS |
127.0.0.1 |
Interface exposed on the host machine |
LAVALINK_PORT |
2333 |
Host port your bot connects to |
JAVA_TOOL_OPTIONS |
-Xms128m -Xmx512m |
Initial and maximum Java heap |
SPOTIFY_ENABLED |
false |
Enable Spotify after configuring credentials |
SPOTIFY_CLIENT_ID |
Empty | Spotify developer app Client ID |
SPOTIFY_CLIENT_SECRET |
Empty | Spotify developer app Client Secret |
SPOTIFY_COUNTRY_CODE |
US |
Preferred Spotify market, such as US or MA |
The Docker container listens internally on port 2333. Change LAVALINK_PORT
to change the host port while keeping the internal port the same. Allow memory
for the JVM and native audio buffers in addition to the configured heap.
Use a Lavalink v4 client in your bot project with these settings:
| Setting | Value |
|---|---|
| Host | 127.0.0.1 |
| Port | 2333, or the LAVALINK_PORT from .env |
| Password | The LAVALINK_SERVER_PASSWORD from .env |
| Secure / TLS | false for this local setup |
The REST API uses /v4; the WebSocket endpoint is /v4/websocket. Your client
normally handles these paths. This starter runs the audio server; player commands,
queues, and Discord credentials belong in your bot project.
Check that the API responds after startup, using your configured password:
curl -H "Authorization: YOUR_PASSWORD" http://127.0.0.1:2333/v4/infoIn PowerShell, use curl.exe for the command above.
Pass these identifiers to your Lavalink client's track-loading method:
| Source | Status | Identifier example |
|---|---|---|
| YouTube | Enabled through YouTube plugin | ytsearch:artist song or a YouTube video / playlist URL |
| YouTube Music | Enabled through YouTube plugin | ytmsearch:artist song |
| Spotify | Enable with credentials below | spsearch:artist song or an https://open.spotify.com/track/... URL |
| SoundCloud | Enabled | scsearch:artist song or a SoundCloud URL |
| Bandcamp | Enabled | A Bandcamp track / album URL |
| Twitch | Enabled | A Twitch stream URL |
| Vimeo | Enabled | A Vimeo video URL |
| Nico | Enabled | A Nico video URL |
| HTTP audio | Enabled | A direct audio-file URL, such as an MP3 |
| Local files | Disabled | Enable explicitly in application.yml if needed |
The enabled flags register each source; individual services can still restrict requests. Spotify artist, album, and playlist links are handled by LavaSrc when the Spotify API permits access. Private or restricted content needs additional authorization and is not configured by this starter.
To try a search directly through the REST API:
curl -G -H "Authorization: YOUR_PASSWORD" --data-urlencode "identifier=ytsearch:artist song" http://127.0.0.1:2333/v4/loadtracksChange the identifier to ytmsearch:artist song, scsearch:artist song, or,
after enabling Spotify, spsearch:artist song. In PowerShell, use curl.exe.
-
Create a Web API app in the Spotify developer dashboard. Copy its Client ID and Client Secret from the app settings. See Spotify's app setup guide for current account and app requirements.
-
Set these values in your local
.env:SPOTIFY_ENABLED=true SPOTIFY_CLIENT_ID=your-client-id SPOTIFY_CLIENT_SECRET=your-client-secret SPOTIFY_COUNTRY_CODE=US
Use a two-letter country code such as
USorMAfor your preferred market. Keep the real credentials in.env, which is excluded from Git. -
Apply the changes:
docker compose up -d --force-recreate docker compose logs -f lavalink
Spotify supplies metadata; LavaSrc resolves playable audio through YouTube. The configuration searches by recording identifier (ISRC) first, then artist/title. Results may differ from the Spotify recording, and Spotify playback also depends on YouTube availability. This behavior is described in LavaSrc's mirroring documentation.
The credentials here use app authentication for accessible Spotify metadata. They do not sign in to a user's account or grant access to private playlists. Spotify API permissions, quotas, and regional availability affect which links can load. Lyrics, recommendations, and other authenticated features are not enabled in this starter.
For other LavaSrc services, such as Apple Music, Deezer, or Tidal, follow the
source-specific setup documentation
and add their required settings to application.yml. These services are not
enabled by the current configuration.
Keep .env.example, application.yml, and compose.yml in Git. .env, downloaded
JARs, and runtime data are ignored. Each clone needs its own .env.
For multiple nodes on the same machine, assign each clone a different
LAVALINK_PORT, such as 2333 and 2334. If two copies have the same folder
name, give Compose a distinct project name, using docker compose -p mybot up -d
and the same -p mybot for logs and shutdown.
For example, a second node can use LAVALINK_PORT=2334 in its .env, then start
with docker compose -p secondbot up -d. Its bot connects to 127.0.0.1:2334.
For a bot in Docker, add the bot service to this Compose file so it joins the
same default network. Connect to host lavalink, port 2333, using the same
password.
For a bot on another machine, set LAVALINK_BIND_ADDRESS=0.0.0.0, use the server's
IP as the bot's host, and restrict access to the bot's IP with your firewall.
The default binding only accepts connections from this machine.
Install Java 17 or newer and download Lavalink.jar from the
4.2.2 release into
this folder. Export the password and start Java:
PowerShell:
$env:LAVALINK_SERVER_PASSWORD = 'YOUR_PASSWORD'
$env:SERVER_ADDRESS = '127.0.0.1'
java -Xms128m -Xmx512m -jar Lavalink.jarLinux / macOS:
export LAVALINK_SERVER_PASSWORD='YOUR_PASSWORD'
export SERVER_ADDRESS='127.0.0.1'
java -Xms128m -Xmx512m -jar Lavalink.jarJava does not automatically load .env. For a different native port, export
SERVER_PORT before launching Java. Native startup downloads plugins to plugins/.
To enable Spotify with native Java, also export SPOTIFY_ENABLED=true,
SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, and optionally SPOTIFY_COUNTRY_CODE
in that terminal before launching Java.
Edit application.yml to change sources, plugin settings, or logging. Edit .env
to change the Docker password, exposed port, Java heap, or Spotify credentials.
Apply changes with:
docker compose up -d --force-recreateVersions are pinned for repeatable clones. To upgrade, change the image version
in compose.yml and the plugin dependency versions in application.yml, then run
docker compose pull followed by the command above.
YouTube availability depends on YouTube's restrictions and the server's IP; enabling the plugin does not guarantee every track will play. See the plugin's documentation for additional configuration if loading or playback fails.
| Symptom | Check |
|---|---|
| Cannot connect to the Docker daemon | Start Docker Desktop or the Docker service; on Windows use Linux containers |
Compose asks for LAVALINK_SERVER_PASSWORD |
Copy .env.example to .env and set a nonempty password |
| Port is already allocated | Change LAVALINK_PORT in that clone's .env |
| Bot cannot connect or receives HTTP 401 | Check host, port, TLS setting, and the exact shared password |
Bot runs in Docker but cannot reach 127.0.0.1 |
Join the same Compose network and use host lavalink, port 2333 |
| Spotify is missing or searches fail | Set SPOTIFY_ENABLED=true, add both credentials, and recreate the container; check Spotify app access |
| Spotify loads metadata but does not play | Inspect the YouTube matching and playback errors in the server logs |
| Plugins fail to download | Check outbound access to maven.lavalink.dev and recreate the container after connectivity is restored |
Inspect status and recent logs:
docker compose ps
docker compose logs --tail 100 lavalinkValidate the Compose file without starting the server:
docker compose --env-file .env.example config --quietAfter startup, use the /v4/info and /v4/loadtracks examples above to check API
access and source loading. Actual voice playback also needs your bot connected
to Discord and forwarding voice updates through its Lavalink client.
This starter uses the official Lavalink server and separately downloaded plugins. Their code, licenses, and release notes are maintained in their upstream repositories. The badges identify the versions pinned in this starter.