Private customers Business customers

Host a Discord bot on a VPSOnline around the clock - even on the smallest plan

A Discord bot running on your own computer goes offline as soon as the computer is switched off. On a VPS, it runs continuously, starts again by itself after a reboot and needs surprisingly little for it: plan XS at €2.95 / month is enough for a single bot. This guide shows which plan to choose and the way from an empty server to a running service - for bots in Python and in Node.js.

From plan XSPython or Node.jssystemd autostartNo open ports needed

Published on

Which plan for a Discord bot?

A typical bot for moderation, role assignment or commands keeps a single connection to Discord open and spends most of its time waiting for events. It needs little memory and almost no computing power. What decides the plan is therefore not the bot itself, but what runs next to it:

PlanRAMCPUNVMePriceBest forOrder
VPS XSOur recommendation1 GB1 vCore5 GB€2.95 / montha single bot, run directly as a serviceOrder XS
VPS S2 GB1 vCore10 GB€4.95 / monthseveral bots, a bot with a database or running in DockerOrder S
VPS M4 GB2 vCore20 GB€6.45 / monthbot plus web dashboard, database and further servicesOrder M
VPS L8 GB4 vCore40 GB€9.45 / monthmany services in parallel on one machineOrder L
VPS XL16 GB4 vCore80 GB€15.95 / monthnot needed for bots aloneOrder XL

XS is the right choice to start with. Go for S at €4.95 / month if several bots run in parallel, a database such as PostgreSQL or MariaDB is added or you prefer to run the bot in a container - Docker itself takes up part of the memory, which is tight on XS.

You are not locked in: you do an upgrade yourself in the customer interface, and the system is moved to the bigger plan without data loss. All five plans with their limits are explained in Prepaid VPS without a contract.

Rent a VPS from €2.95 / month

Prepaid without a contract, full root access.

View plans & prices

Preparation

The VPS should be set up and secured - at a minimum with system updates installed, SSH login by key and a firewall. The commands here apply to Debian and Ubuntu.

The bot should not run as root. A bot processes input from strangers, and a bug in the code should not open up the whole system. So create a dedicated user without a login:

sudo adduser --disabled-login --gecos "Discord bot" bot

You bring the code onto the server with git clone or via SFTP, into a directory below /home/bot. In the examples, it is called /home/bot/mybot.

Option A: bot in Python

For bots based on discord.py or a related library, install Python together with the module for virtual environments:

sudo apt update
sudo apt install python3 python3-venv git -y

The dependencies belong in a virtual environment in the project folder, not in the system. That way, system updates leave the bot untouched:

sudo -u bot -s
cd /home/bot/mybot
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
exit

If your project has no requirements.txt, install the library directly, for example with .venv/bin/pip install discord.py.

Option B: bot in Node.js

For bots based on discord.js, install Node.js and npm:

sudo apt update
sudo apt install nodejs npm git -y
node --version

Compare the version shown with what your discord.js release requires - the minimum version is in the library's documentation and in the engines field of its package.json. If the version from your distribution's package sources is too old, install a current LTS release via the official NodeSource packages.

sudo -u bot -s
cd /home/bot/mybot
npm ci
exit

npm ci installs exactly the versions from package-lock.json. If the file is missing, use npm install.

Store the token securely

The bot token is your bot's password. Whoever has it controls the bot with all the permissions it holds on your servers. It therefore belongs neither in the source code nor in a Git repository, but in a file that only the bot user may read:

sudo -u bot nano /home/bot/mybot/.env
DISCORD_TOKEN=your-token-goes-here
sudo chmod 600 /home/bot/mybot/.env

The file contains one line per variable, without quotation marks and without export. Your code reads the value from the environment - in Python via os.environ["DISCORD_TOKEN"], in Node.js via process.env.DISCORD_TOKEN. If a token ever becomes public, generate a new one in the Discord Developer Portal immediately; the old one is invalid from then on.

Set up autostart with systemd

A bot you start in an SSH session ends with the session. As a systemd service, it runs independently of that and starts again by itself after a server reboot and after a crash:

sudo nano /etc/systemd/system/discordbot.service
[Unit]
Description=Discord bot
After=network-online.target
Wants=network-online.target

[Service]
User=bot
Group=bot
WorkingDirectory=/home/bot/mybot
EnvironmentFile=/home/bot/mybot/.env
ExecStart=/home/bot/mybot/.venv/bin/python bot.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

The ExecStart line applies to Python. For Node.js, it reads ExecStart=/usr/bin/node index.js - adjust the file name to your bot's entry point. Then enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable --now discordbot
sudo systemctl status discordbot --no-pager

The status should report active (running), and the bot shows up as online in Discord. You read the running output, including error messages, with sudo journalctl -u discordbot -f.

Firewall: open nothing

A Discord bot establishes its connection outward by itself. It accepts no incoming connections and therefore needs no open port - unlike a web server or a voice server. The firewall stays as restrictive as you set it up.

That only changes once the bot comes with a web dashboard or an endpoint for webhooks. Then a web server sits in front of it as a reverse proxy, and only its ports 80 and 443 are opened.

Updates and backups

An update consists of three steps: fetch the new code, update the dependencies, restart the service.

sudo -u bot git -C /home/bot/mybot pull
sudo systemctl restart discordbot

If the dependencies have changed, run pip install -r requirements.txt or npm ci once more as the bot user before restarting.

There is little to back up, but that little is important: the .env, the configuration and everything the bot stores itself - often an SQLite file or a JSON directory in the project folder. Automatic backups are not part of the plan. A nightly copy to an external destination, for example with a cron job and rsync or restic, takes care of it.

Prefer a container?

Nesting is enabled on our VPS plans, so Docker and Docker Compose run. For a bot, that is worth it if it already comes with a Dockerfile or if you want to keep several bots cleanly separated. Plan for S instead of XS in that case.

For a single bot, the systemd route is leaner: less memory, fewer moving parts and the same reliability on restart.

Frequently asked questions

For a single bot that runs directly as a systemd service, plan XS is enough. For several bots, a bot with its own database or running in Docker, plan S is the right size.

No. The bot establishes the connection to Discord outward by itself and accepts no incoming connections. An open port is only needed once a web dashboard or a webhook endpoint is added.

Yes, once it is set up as a systemd service and enabled with systemctl enable. With Restart=always, it also restarts automatically after a crash.

Yes. Each bot gets its own directory, its own .env and its own systemd unit. For several bots in parallel, plan S makes more sense than XS.

Because then the bot is only online while your computer is running and connected. On the VPS, it runs continuously, independent of your computer and your internet connection.

A VPS for your Discord bot

A single bot already runs on plan XS. For several bots, a database or Docker, S is the right size. Full root access, prepaid without a contract, located in Frankfurt am Main.

View VPS plans & prices