TutorialsAugust 4, 20264 min read

How to Deploy a Discord Bot with Docker

Containerize your Discord bot with a Dockerfile and run it on a VPS: build the image, pass the token as an env var, and auto-restart with a restart policy.

NBy Nxeon

Docker packages your Discord bot and all its dependencies into one portable image that runs identically on any host. This guide containerizes a bot and deploys it on a VPS with auto-restart. For the non-Docker path, see how to host a Discord bot on a VPS 24/7.

Why Docker for a bot

  • Reproducible: the image bundles the runtime, libraries, and system deps (like ffmpeg).
  • Portable: move it between servers or providers with no reinstall.
  • Isolated: each bot runs in its own container, so their dependencies never clash.
  • Simple restarts: a restart policy keeps it online on crash and reboot.

Step 1: Install Docker on the VPS

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

If Docker is new to you, our how to run Docker on a VPS guide covers the basics.

Step 2: Write a Dockerfile

For a Node.js (discord.js) bot, create Dockerfile in your project root:

FROM node:20-slim

# Install ffmpeg only if it's a music bot
# RUN apt-get update && apt-get install -y ffmpeg && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .

CMD ["node", "index.js"]

For a Python bot:

FROM python:3.12-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

CMD ["python", "bot.py"]
Building a website with Claude AI inside the Nxeon control panel
Building a website with Claude AI inside the Nxeon control panel

Step 3: Add a .dockerignore

Keep secrets and junk out of the image:

node_modules
.env
.git
*.log

Step 4: Build the image

docker build -t my-discord-bot .

Step 5: Run the container with the token as an env var

Never bake the token into the image. Pass it at runtime, and set a restart policy so it stays online:

docker run -d \
  --name discord-bot \
  --restart unless-stopped \
  --env-file .env \
  my-discord-bot

--restart unless-stopped brings the bot back on crash and after a server reboot. --env-file .env injects your DISCORD_TOKEN without storing it in the image.

Step 6: Manage the container

docker logs -f discord-bot     # tail logs
docker restart discord-bot     # restart
docker stop discord-bot        # stop
docker rm -f discord-bot       # remove

To deploy an update: rebuild and recreate.

git pull
docker build -t my-discord-bot .
docker rm -f discord-bot
docker run -d --name discord-bot --restart unless-stopped --env-file .env my-discord-bot

Optional: docker compose

For a bot plus a database, a docker-compose.yml is tidier:

services:
  bot:
    build: .
    restart: unless-stopped
    env_file: .env

Then docker compose up -d --build. Compose shines when your bot needs Postgres or Redis alongside it.

Docker vs PM2

Docker gives you full reproducibility and isolation; PM2 is lighter if you're only running Node bots and want quick log access — see how to keep a Discord bot online with PM2. Many people use PM2 for simple bots and Docker once they need extra services. Either way, secure the host — securing your first Linux VPS: 10 steps.

Passing config and persisting data

Beyond the token, pass any config as environment variables in your .env, and mount a volume if your bot writes files or a local database:

docker run -d --name discord-bot --restart unless-stopped \
  --env-file .env \
  -v /home/bot/data:/app/data \
  my-discord-bot

The -v bind mount keeps data on the host so it survives container rebuilds. For a bot plus Postgres, a Compose file wires them together on a private network.

Keeping images small and current

  • Use -slim base images and npm ci --omit=dev / pip install --no-cache-dir to keep images lean.
  • Rebuild periodically to pick up base-image security patches.
  • Keep a .dockerignore so node_modules, .git, and .env never bloat or leak into the image.

Troubleshooting

  • Container exits immediately: run docker logs discord-bot — usually a bad token or a dependency you forgot to install in the image.
  • ffmpeg not found (music bot): add apt-get install -y ffmpeg to the Dockerfile.
  • Changes not taking effect: you rebuilt but didn't recreate the container — docker rm -f then docker run again, or use Compose's --build.

FAQ

How do I pass my bot token to a container safely?

Use --env-file .env or -e DISCORD_TOKEN=... at run time, and add .env to .dockerignore so it's never baked into the image.

How do I keep the container running after a reboot?

Add --restart unless-stopped (or always). Docker's daemon restarts the container on crash and after the server boots.

Do I need ffmpeg in the image for a music bot?

Yes — add RUN apt-get install -y ffmpeg to the Dockerfile. The base slim images don't include it.

Is Docker overkill for a small bot?

For a single simple bot, PM2 or systemd is lighter. Docker pays off when you want reproducible builds, easy provider moves, or a bot bundled with a database.

Deploy your containerized bot on Docker hosting from Nxeon — NVMe VPS with full root access, or the general Discord bot hosting plans if you're keeping it simple.

#discord bot#docker#containers#deployment#vps#seobatch

Deploy your first server in under a minute

Creating an account is free and takes no card details. You pay when you deploy — choose a billing term and pay from your wallet or by card at checkout.