Tutorials

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.

NXNxeonNxeon editorialAugust 4, 2026 4 min read
Quick answer

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.

Topic
Tutorials
Read time
4 min read
Covers
discord bot, docker, containers
Last updated
August 5, 2026

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.

Cloud VPS hosting

Deploy in seconds, not weekends

Explore Cloud VPS hosting ★★★★★ Instant deploy · full root · 24/7 support
#discord bot#docker#containers#deployment#vps#seobatch
NX

Nxeon · Nxeon editorial

★★★★★ Straight-talking guides from the team that runs the servers.

Cloud VPS hosting

Deploy in seconds, not weekends

Full root access on NVMe cloud VPS with instant deployment — the flexible way to host anything.

Explore Cloud VPS hosting ★★★★★ Instant deploy · full root · 24/7 support