Tutorials

Running Lavalink on Docker - Complete Guide

February 25, 2026
14 min read read
M
Manas

Docker provides an excellent way to run Lavalink with consistent environments and easy deployment. This guide covers everything from basic setup to production-ready configurations.

Benefits

  • Consistency - Same environment everywhere
  • Isolation - No conflicts with other applications
  • Easy Updates - Pull new image, restart container
  • Portability - Deploy anywhere Docker runs
  • Resource Control - Set memory and CPU limits

When to Use Docker

Docker is ideal when:

  • Running multiple services on one server
  • Need reproducible deployments
  • Want easy scaling and updates
  • Using container orchestration (Kubernetes)

Prerequisites

Install Docker

Ubuntu/Debian:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

Verify installation:

docker --version
docker compose version

Basic Docker Setup

Using Pre-built Image

The easiest approach uses the official Lavalink image:

docker run -d \
  --name lavalink \
  -p 2333:2333 \
  -v $(pwd)/application.yml:/opt/Lavalink/application.yml \
  ghcr.io/lavalink-devs/lavalink:4

Create application.yml

server:
  port: 2333
  address: 0.0.0.0

lavalink:
  server:
    password: "your_secure_password"
    sources:
      youtube: true
      soundcloud: true
      bandcamp: true
      twitch: true
      http: true
      local: false

Docker Compose Setup

Basic docker-compose.yml

version: '3.8'

services:
  lavalink:
    image: ghcr.io/lavalink-devs/lavalink:4
    container_name: lavalink
    restart: unless-stopped
    ports:
      - "2333:2333"
    volumes:
      - ./application.yml:/opt/Lavalink/application.yml
    environment:
      - _JAVA_OPTIONS=-Xmx1G

Start with Docker Compose

docker compose up -d

View Logs

docker compose logs -f lavalink

Custom Dockerfile

For more control, create a custom Dockerfile:

Dockerfile

FROM eclipse-temurin:21-jre-alpine

# Create app directory
WORKDIR /opt/Lavalink

# Download Lavalink
ARG LAVALINK_VERSION=4.0.4
RUN wget -O Lavalink.jar \
    "https://github.com/lavalink-devs/Lavalink/releases/download/${LAVALINK_VERSION}/Lavalink.jar"

# Copy configuration
COPY application.yml .

# Expose port
EXPOSE 2333

# Set JVM options
ENV JAVA_OPTS="-Xms256M -Xmx1G -XX:+UseG1GC"

# Run Lavalink
CMD java $JAVA_OPTS -jar Lavalink.jar

Build and Run

docker build -t my-lavalink .
docker run -d -p 2333:2333 my-lavalink

Production Configuration

Optimized docker-compose.yml

version: '3.8'

services:
  lavalink:
    image: ghcr.io/lavalink-devs/lavalink:4
    container_name: lavalink
    restart: always
    ports:
      - "2333:2333"
    volumes:
      - ./application.yml:/opt/Lavalink/application.yml:ro
      - ./plugins:/opt/Lavalink/plugins:ro
    environment:
      - _JAVA_OPTIONS=-Xms512M -Xmx1G -XX:+UseG1GC -XX:+ParallelRefProcEnabled
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 1.5G
        reservations:
          cpus: '0.5'
          memory: 512M
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "-", "http://localhost:2333/version"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Production application.yml

server:
  port: 2333
  address: 0.0.0.0

lavalink:
  server:
    password: "${LAVALINK_PASSWORD:changeme}"
    sources:
      youtube: true
      soundcloud: true
      bandcamp: true
      twitch: true
      http: true
      local: false
    bufferDurationMs: 400
    frameBufferDurationMs: 5000
    youtubePlaylistLoadLimit: 6
    playerUpdateInterval: 5
    youtubeSearchEnabled: true
    soundcloudSearchEnabled: true
    gc-warnings: true

metrics:
  prometheus:
    enabled: true
    endpoint: /metrics

logging:
  level:
    root: INFO
    lavalink: INFO

Adding Plugins

Plugin Directory Structure

lavalink/
├── docker-compose.yml
├── application.yml
└── plugins/
    └── youtube-plugin-1.0.0.jar

docker-compose.yml with Plugins

services:
  lavalink:
    image: ghcr.io/lavalink-devs/lavalink:4
    volumes:
      - ./application.yml:/opt/Lavalink/application.yml
      - ./plugins:/opt/Lavalink/plugins

application.yml with Plugins

plugins:
  youtube:
    enabled: true
    clients:
      - MUSIC
      - WEB

Multi-Node Setup

docker-compose.yml for Multiple Nodes

version: '3.8'

services:
  lavalink-1:
    image: ghcr.io/lavalink-devs/lavalink:4
    container_name: lavalink-1
    ports:
      - "2333:2333"
    volumes:
      - ./application.yml:/opt/Lavalink/application.yml
    environment:
      - _JAVA_OPTIONS=-Xmx1G

  lavalink-2:
    image: ghcr.io/lavalink-devs/lavalink:4
    container_name: lavalink-2
    ports:
      - "2334:2333"
    volumes:
      - ./application.yml:/opt/Lavalink/application.yml
    environment:
      - _JAVA_OPTIONS=-Xmx1G

Networking

Internal Network

version: '3.8'

services:
  lavalink:
    image: ghcr.io/lavalink-devs/lavalink:4
    networks:
      - bot-network
    # No ports exposed externally

  discord-bot:
    build: ./bot
    networks:
      - bot-network
    environment:
      - LAVALINK_HOST=lavalink
      - LAVALINK_PORT=2333

networks:
  bot-network:
    driver: bridge

Connecting from Bot

When both services are on the same Docker network:

const nodes = [{
  host: 'lavalink',  // Container name
  port: 2333,
  password: 'your_password'
}];

Monitoring

Add Prometheus and Grafana

version: '3.8'

services:
  lavalink:
    image: ghcr.io/lavalink-devs/lavalink:4
    ports:
      - "2333:2333"
    volumes:
      - ./application.yml:/opt/Lavalink/application.yml

  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    depends_on:
      - prometheus

prometheus.yml

scrape_configs:
  - job_name: 'lavalink'
    static_configs:
      - targets: ['lavalink:2333']

Common Commands

Container Management

# Start
docker compose up -d

# Stop
docker compose down

# Restart
docker compose restart

# View logs
docker compose logs -f

# Check status
docker compose ps

Updates

# Pull latest image
docker compose pull

# Recreate container with new image
docker compose up -d --force-recreate

Debugging

# Enter container shell
docker exec -it lavalink sh

# Check resource usage
docker stats lavalink

# Inspect container
docker inspect lavalink

Troubleshooting

Container Keeps Restarting

Check logs for errors:

docker logs lavalink

Common causes:

  • Invalid application.yml
  • Insufficient memory
  • Port already in use

Cannot Connect to Lavalink

Verify container is running:

docker ps

Check port mapping:

docker port lavalink

High Memory Usage

Set memory limits in docker-compose.yml and JVM options.

Conclusion

Docker simplifies Lavalink deployment with consistent environments and easy management. Use the production configuration for reliable operation and add monitoring for visibility into performance.

HeavenCloud provides managed Lavalink hosting that handles all this infrastructure, letting you focus on your music bot instead of container management.

Start building your community

Deploy high-performance Discord bots, Lavalink nodes, and VPS servers with instant setup on HeavenCloud.