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.

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"]

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
-slimbase images andnpm ci --omit=dev/pip install --no-cache-dirto keep images lean. - Rebuild periodically to pick up base-image security patches.
- Keep a
.dockerignoresonode_modules,.git, and.envnever 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 ffmpegto the Dockerfile. - Changes not taking effect: you rebuilt but didn't recreate the container —
docker rm -fthendocker runagain, 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.