Skip to main content
JoBot runs entirely inside Docker, so you don’t need to install .NET or any other runtime. You will need a machine that can run Docker, three API credentials, and about five minutes to get your first AI response in Discord.
1

Register a Discord application and bot

  1. Go to the Discord Developer Portal and click New Application.
  2. Give it a name (e.g. “JoBot”), then navigate to the Bot tab.
  3. Click Reset Token and copy the token — this is your DISCORD_TOKEN.
  4. Under Privileged Gateway Intents, enable Message Content Intent.
  5. Navigate to OAuth2 → URL Generator. Select the bot scope, then grant these bot permissions:
    • Read Messages / View Channels
    • Send Messages
    • Connect (voice)
    • Speak (voice)
  6. Copy the generated URL, open it in your browser, and invite the bot to your server.
2

Pull the Docker image

Pull the latest JoBot image from the GitHub Container Registry:
docker pull ghcr.io/jeppevinkel/jobot:latest
3

Create docker-compose.yml

Create a docker-compose.yml file in a new directory. JoBot requires a Lavalink sidecar for audio routing — the snippet below sets both up:
docker-compose.yml
services:
  JoBot:
    restart: unless-stopped
    image: ghcr.io/jeppevinkel/jobot:latest
    depends_on:
      - lavalink
    environment:
      # Required
      - Anthropic__Token=${ANTHROPIC_API_KEY}
      - Discord__Token=${DISCORD_TOKEN}
      - Lavalink__Passphrase=${LAVALINK_PASSPHRASE}
      - Subsonic__BaseUrl=${SUBSONIC_BASE_URL}
      - Subsonic__Username=${SUBSONIC_USERNAME}
      - Subsonic__Password=${SUBSONIC_PASSWORD}
      - ConnectionStrings__JoBot=Data Source=/app/config/jobot.db

      # Optional — Lavalink (defaults shown)
      - Lavalink__BaseAddress=http://lavalink:2333

      # Optional — AI tuning (defaults shown)
      - Ai__Model=claude-sonnet-4-6
      - Ai__MaxTokens=4096
      - Ai__Temperature=0.7
      - Ai__MaxToolIterations=50
      - Ai__MaxHistoryMessages=40

      # Optional — per-guild defaults (defaults shown)
      - GuildDefaults__MaxHistoryMessages=20
      - GuildDefaults__AiTemperature=0.7
      - GuildDefaults__MusicVolume=0.5

  lavalink:
    image: ghcr.io/lavalink-devs/lavalink:4
    environment:
      - LAVALINK_SERVER_PASSWORD=${LAVALINK_PASSPHRASE}
4

Create .env with required variables

In the same directory as your docker-compose.yml, create a .env file. Docker Compose reads this file automatically and substitutes the values into the service environment.
.env
# Required
DISCORD_TOKEN=your-discord-bot-token
ANTHROPIC_API_KEY=your-anthropic-api-key
LAVALINK_PASSPHRASE=choose-any-secure-passphrase

# Optional — remove if you don't have a Subsonic server
SUBSONIC_BASE_URL=https://music.example.com
SUBSONIC_USERNAME=your-subsonic-username
SUBSONIC_PASSWORD=your-subsonic-password
DISCORD_TOKEN and ANTHROPIC_API_KEY are always required. LAVALINK_PASSPHRASE can be any string you choose — it only needs to match between the two containers. The Subsonic variables are optional; remove or leave them blank if you don’t have a Subsonic server.
5

Start the bot

From the directory containing your docker-compose.yml, run:
docker compose up -d
Both the JoBot and Lavalink containers will start in the background. Check the logs if something doesn’t come up:
docker compose logs -f JoBot

First interaction

Once the bot is online in your server, @mention it in any text channel to start a conversation:
@JoBot what can you help me with?
JoBot replies to direct @mentions and to replies on its own messages. It does not respond to messages that don’t mention it. If you’d like it to join a voice channel and play music, ask it directly:
@JoBot join my voice channel and play something from YouTube
The environment variables above cover the essentials. For a full reference of every configuration option — including ElevenLabs TTS, AI model tuning, and per-guild defaults — see Environment variables.