PlexBot runs as two Docker containers — the bot itself (.NET 9) and Lavalink (Java audio server). The install scripts handle everything, but this guide covers the Docker setup in detail for customization and troubleshooting.
- Docker Engine 20.10+
- Docker Compose v2+
- Git
PlexBot/
├── Install/Docker/
│ ├── dockerfile # Multi-stage .NET 9 build
│ ├── docker-compose.yml # Orchestrates PlexBot + Lavalink
│ ├── lavalink.application.yml # Lavalink server config
│ ├── startup.sh # Container entrypoint
│ └── plugins/ # Lavalink plugins (YouTube, etc.)
├── .env # Secrets (tokens, passwords)
├── config.fds # Application settings (auto-created if missing)
└── logs/ # Persisted log files
└── lavalink/ # Lavalink logs
- Image: Built from
Install/Docker/dockerfile - Container name:
PlexBot - Depends on: Lavalink (starts after Lavalink is ready)
- Volumes:
../../→/source(project root for live source access)../../data→/app/data(persistent data)../../logs→/app/logs(bot logs)../../.env→/app/.env(secrets)../../Images→/app/Images(player assets)config.fdsis auto-managed bystartup.sh— copies your custom config from the project root if it exists, otherwise creates one from the template
- Network:
plexbot-network(bridge)
- Image:
ghcr.io/lavalink-devs/lavalink:4 - Container name:
LavaLink - Ports:
2333:2333(configurable viaLAVALINK_SERVER_PORTin.env) - Volumes:
lavalink.application.yml→ Lavalink configplugins/→ Lavalink plugins../../logs/lavalink→ Lavalink log files (persisted)
- Network:
plexbot-network(bridge)
The build uses a multi-stage .NET 9 SDK image:
Build stage: Restores and publishes the .NET project
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
WORKDIR /source
COPY . .
RUN dotnet restore
RUN dotnet publish -c Release -o /appRuntime stage: Uses the SDK image (not just runtime) to support live source rebuilds. Installs font packages for ImageSharp text rendering:
fonts-dejavu,fonts-liberation— Latin textfonts-noto,fonts-noto-cjk,fonts-noto-color-emoji— CJK characters and emojifonts-ipafont-gothic,fonts-ipafont-mincho— Japanese text
# Both services
docker-compose logs
# Follow PlexBot logs
docker-compose logs -f plexbot
# Follow Lavalink logs
docker-compose logs -f lavalinkBot logs are also saved to logs/ and Lavalink logs to logs/lavalink/ on the host.
docker-compose up -d # Start
docker-compose down # Stop
docker-compose restart plexbot # Restart just the bot
docker-compose up -d --build # Rebuild and restartdocker-compose ps # List containers
docker stats # Resource usagePull the latest code and rebuild:
git pull
docker-compose down
docker-compose up -d --buildOr just run the install script again — it handles this automatically.
Two optional settings in docker-compose.yml help with audio stuttering:
Uncomment _JAVA_OPTIONS in .env to switch Lavalink's JVM to ZGC:
_JAVA_OPTIONS=-XX:+UseZGC -XX:+ZGenerational -Xms256m -Xmx512mUncomment cpuset and cpu_shares in docker-compose.yml to reserve CPU cores for Lavalink:
cpuset: "0,1"
cpu_shares: 2048See the README Performance Tuning section for details.
To use a Lavalink server running on a different machine, update .env:
LAVALINK_HOST=192.168.1.100
LAVALINK_SERVER_PORT=2333
LAVALINK_SERVER_PASSWORD=mypassword
LAVALINK_SECURE=falseThen remove or comment out the lavalink service and depends_on block in docker-compose.yml.
| Resource | Minimum |
|---|---|
| CPU | 2 cores |
| RAM | 2 GB |
| Disk | 1 GB free |
| Network | Stable connection to Discord and Plex |
- Store all tokens and passwords in
.env— never indocker-compose.ymlor code - Don't expose the Lavalink port publicly unless you need remote access
.envis.gitignored — never commit it
See the Troubleshooting Guide for common issues.