RDP Monster

Discord-Bot auf einem VPS hosten: 24/7 online bleiben

Discord-Bot auf einem VPS hosten: 24/7 online bleiben

Warum Discord-Bots ausgerechnet auf einem VPS online bleiben

Ein Discord-Bot ist keine Webseite. Nach dem Login hält er eine dauerhafte WebSocket-Verbindung zum Gateway von Discord und muss fortlaufend Heartbeats beantworten; sobald der Prozess stoppt, erscheint der Bot offline und jeder Befehl schlägt fehl. Diese eine Anforderung – ein Prozess, der nie schläft – schließt die meisten „kostenlosen“ Hostings aus:

  • Heroku hat seine kostenlosen Dynos im November 2022 abgeschafft.
  • Replit hält kostenlose Projekte nicht mehr am Laufen; Always-on gibt es nur noch in kostenpflichtigen Deployments.
  • Glitch hat sein App-Hosting 2025 eingestellt.
  • Kostenlose Web-Tarife, die bei Inaktivität einschlafen, trennen jedes Mal die Gateway-Verbindung; für die Nutzer ist der Bot damit schlicht offline.

Discord-Bot-Hosting auf einem VPS behebt das an der Wurzel: eine Linux-Maschine mit Root-Zugriff, die rund um die Uhr läuft und auf der der Bot einfach ein weiterer vom Init-System verwalteter Dienst ist. Diese Anleitung baut das auf Ubuntu 24.04 auf (gilt auch für 22.04 und Debian 12), mit discord.py und discord.js, und behandelt danach Token-Handhabung, Neustarts, Logs, Updates und Speicher.

Den VPS vorbereiten: ein eigener Benutzer und eine Laufzeitumgebung

Zuerst die Haustür sichern: SSH unter Ubuntu aktivieren und härten – mit Schlüsselauthentifizierung, ohne Root-Login und mit ufw. Ein Bot baut die Verbindung zu Discord selbst auf und braucht keine eingehenden Ports, die Firewall kann also außer SSH alles blockieren.

Schritt 1: ein unprivilegiertes Konto für den Bot anlegen

sudo useradd -r -m -d /opt/mybot -s /usr/sbin/nologin bot

Ein eigenes Konto sorgt dafür, dass ein fehlerhafter Bot oder eine kompromittierte npm- oder PyPI-Abhängigkeit weder Ihre SSH-Schlüssel lesen noch andere Dienste anfassen kann. Alles liegt in /opt/mybot und gehört dem Benutzer bot.

Schritt 2 (Python): discord.py in einer virtuellen Umgebung installieren

sudo apt update && sudo apt install -y python3 python3-venv python3-pip
sudo -u bot python3 -m venv /opt/mybot/.venv
sudo -u bot /opt/mybot/.venv/bin/pip install -U discord.py python-dotenv

discord.py 2.x setzt Python 3.8 oder neuer voraus; Ubuntu 24.04 liefert 3.12 und 22.04 liefert 3.10, der Interpreter der Distribution genügt also. discord.py[voice] und ffmpeg nur für Sprachkanäle ergänzen.

Schritt 3 (Node.js): aktuelles LTS und discord.js installieren

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
sudo -u bot bash -c 'cd /opt/mybot && npm init -y && npm install discord.js dotenv'

Ubuntus eigenes nodejs-Paket hinkt dem Upstream deutlich hinterher und discord.js v14 braucht eine moderne Laufzeitumgebung – nehmen Sie daher NodeSource (siehe oben) oder nvm für ein aktuelles LTS. Bei nvm which node ausführen und diesen absoluten Pfad in der Service-Unit eintragen.

Den Token aus dem Code heraushalten: die .env-Datei

Der Bot-Token ist ein Passwort mit voller Kontrolle über den Bot: niemals in bot.py oder index.js einfügen, niemals committen. Legen Sie ihn in /opt/mybot/.env ab, nur für das Bot-Konto lesbar, und benutzen Sie einen Editor statt echo, denn ein auf der Kommandozeile getippter Token landet in der Shell-History:

sudo -u bot nano /opt/mybot/.env        # one line: DISCORD_TOKEN=your-token-here
sudo chmod 600 /opt/mybot/.env
echo ".env" | sudo -u bot tee -a /opt/mybot/.gitignore

Das Format ist ein KEY=value pro Zeile, ohne Anführungszeichen, ohne export. python-dotenv und das npm-Paket dotenv lesen sie, und systemd kann dieselbe Datei mit EnvironmentFile= einspeisen (nächster Abschnitt); beides zu kombinieren ist unschädlich, da keine der Bibliotheken eine bereits vorhandene Variable überschreibt. Sollte der Token je durchsickern, setzen Sie ihn sofort im Developer Portal unter Bot → Reset Token zurück.

Ein minimaler Bot in discord.py und discord.js

Beide Beispiele lesen den Token aus der Umgebung, aktivieren den Message-Content-Intent und antworten auf !ping. Legen Sie im Developer Portal eine Anwendung an, fügen Sie einen Bot-Benutzer hinzu, kopieren Sie den Token (er wird nur einmal angezeigt), aktivieren Sie Message Content Intent unter Bot → Privileged Gateway Intents und laden Sie den Bot über den OAuth2-URL-Generator mit dem Scope bot auf einen Testserver ein.

discord.py: /opt/mybot/bot.py

import os
import discord
from dotenv import load_dotenv

load_dotenv()

intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f"Logged in as {client.user}")

@client.event
async def on_message(message):
    if message.author == client.user:
        return
    if message.content == "!ping":
        await message.channel.send("pong")

client.run(os.environ["DISCORD_TOKEN"])

discord.js: /opt/mybot/index.js

require("dotenv").config();
const { Client, GatewayIntentBits, Events } = require("discord.js");

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
});

client.once(Events.ClientReady, (c) => {
  console.log(`Logged in as ${c.user.tag}`);
});

client.on(Events.MessageCreate, (message) => {
  if (message.author.bot) return;
  if (message.content === "!ping") message.reply("pong");
});

client.login(process.env.DISCORD_TOKEN);

Führen Sie ihn einmal im Vordergrund aus: sudo -u bot /opt/mybot/.venv/bin/python /opt/mybot/bot.py oder sudo -u bot node /opt/mybot/index.js, warten Sie auf Logged in as, senden Sie !ping und drücken Sie dann Strg-C. Derzeit lebt der Bot nur so lange wie Ihre SSH-Sitzung: Beim Schließen des Terminals geht ein SIGHUP an die Kindprozesse und der Bot stirbt.

Mit systemd und Restart=always betreiben

systemd ist ohnehin das Init-System von Ubuntu, deshalb ist eine Service-Unit der sauberste Weg, den Bot nach Abmeldung, Absturz und Neustart online zu halten: kein zusätzlicher Daemon, und die Logs landen im Journal.

Schritt 1: die Unit schreiben

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

[Service]
Type=simple
User=bot
Group=bot
WorkingDirectory=/opt/mybot
EnvironmentFile=/opt/mybot/.env
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/mybot/.venv/bin/python /opt/mybot/bot.py
Restart=always
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/mybot

[Install]
WantedBy=multi-user.target

Für discord.js setzen Sie ExecStart=/usr/bin/node /opt/mybot/index.js und lassen die Zeile PYTHONUNBUFFERED weg. Die entscheidenden Direktiven:

  • Restart=always startet den Prozess bei jedem Beenden neu, egal ob Absturz oder sauberes sys.exit(); RestartSec=5 verhindert, dass ein sofort sterbender Bot (falscher Token, Syntaxfehler) in einer engen Schleife kreist.
  • Wants=/After=network-online.target verzögern den Start, bis das Netzwerk steht, damit der erste Login nach einem Neustart nicht am DNS scheitert.
  • PYTHONUNBUFFERED=1: Ohne Terminal puffert Python stdout blockweise, und print()-Zeilen erreichen das Journal erst Minuten später oder erst beim Beenden.
  • Die Zeilen Protect*, PrivateTmp und NoNewPrivileges machen den Rest des Dateisystems für den Bot schreibgeschützt oder unsichtbar; jedes Verzeichnis, in das er schreiben muss, gehört in ReadWritePaths=.

Schritt 2: aktivieren, starten und prüfen

sudo systemctl daemon-reload
sudo systemctl enable --now mybot
systemctl status mybot
sudo systemctl kill --signal=KILL mybot   # simulate a crash; status is active again after 5 s

enable legt den Boot-Symlink an und --now startet die Unit. Die kill-Zeile ist der eigentliche Test: Zeigt systemctl status mybot wenige Sekunden später active (running), funktioniert die Restart-Policy, und ein sudo reboot belegt den Boot-Pfad. Um ihn neben allen anderen Diensten zu sehen, können Sie die laufenden Dienste mit systemctl auflisten; er erscheint als mybot.service, und systemctl is-enabled mybot bestätigt, dass er nach einem Neustart wiederkommt.

Alternative: pm2 – und der Vergleich mit screen, nohup und Docker

Jede Methode, einen Bot am Leben zu halten, beantwortet drei Fragen: Übersteht sie die SSH-Abmeldung, startet sie nach einem Absturz neu und startet sie beim Neustart mit?

MethodeÜbersteht SSH-AbmeldungNeustart nach AbsturzStart beim BootenFazit
nohup / &JaNeinNeinNur für schnelle Tests.
screen / tmuxJaNeinNein, außer per SkriptZum Debuggen, nicht für den Produktivbetrieb.
pm2JaJaJa, nach pm2 startup + pm2 saveGut für Node.js-Teams; ein CLI für Logs und Neustarts.
systemd-UnitJaJa (Restart=)Ja (enable)Empfohlen; keine Zusatzsoftware, Härtung inklusive.
Docker, restart: unless-stoppedJaJaJa, mit dem Docker-DaemonGut, wenn der Bot ohnehin als Image ausgeliefert wird.

pm2 ist die beliebte Wahl in der Node.js-Welt und kommt auch mit Python zurecht. Führen Sie es unter dem Konto aus, dem der Bot gehört:

sudo npm install -g pm2
cd /opt/mybot
pm2 start index.js --name mybot
pm2 start bot.py --name mybot --interpreter /opt/mybot/.venv/bin/python   # Python variant
pm2 save
pm2 startup                    # prints a sudo command to run once
pm2 logs mybot
pm2 install pm2-logrotate      # ~/.pm2/logs/ otherwise grows forever

pm2 startup erzeugt eine systemd-Unit pm2-<user>, die Ihre gespeicherte Prozessliste beim Booten wiederherstellt; pm2 setzt also auf systemd auf, statt es zu ersetzen – das ehrliche Argument dafür, für einen einzelnen Bot direkt systemd zu nehmen. pm2 lohnt sich bei mehreren Node-Prozessen oder in einem Team, das es ohnehin kennt.

Wenn Sie Container bevorzugen, ist restart: unless-stopped in einer Compose-Datei das Äquivalent; die Anleitung zum Installieren von Docker auf einem Ubuntu-VPS behandelt Engine, Compose und das Boot-Verhalten. Der dortige ufw-Vorbehalt betrifft einen Bot nicht, da er keine Ports veröffentlicht.

Logs, Updates und Speicherdimensionierung

Logs

journalctl -u mybot -f                    # follow live
journalctl -u mybot --since "1 hour ago"
journalctl -u mybot -p err -b             # errors since boot
sudo journalctl --vacuum-size=200M        # cap journal size

journald rotiert und komprimiert von selbst. Schreibt der Bot eine eigene Logdatei, verwenden Sie logging.handlers.RotatingFileHandler in Python oder einen rotierenden Transport mit pino oder winston in Node, damit ein geschwätziger Handler die Platte nicht vollschreibt.

Updates

cd /opt/mybot
sudo -u bot git pull
sudo -u bot .venv/bin/pip install -U -r requirements.txt   # Node: sudo -u bot npm ci
sudo systemctl restart mybot

Ein Neustart trennt die Gateway-Verbindung für wenige Sekunden; die Bibliothek verbindet sich neu und den Nutzern fällt es selten auf. Pinnen Sie Bibliotheksversionen in requirements.txt oder package-lock.json und lesen Sie das Changelog vor einem Major-Sprung. Halten Sie das Betriebssystem mit sudo apt update && sudo apt upgrade oder unattended-upgrades aktuell.

Wie viel RAM braucht der Bot?

Dimensionieren Sie nicht nach Pauschalwerten, sondern messen Sie. systemctl status mybot gibt eine Zeile Memory: aus, und pm2 list zeigt dasselbe. Ein reiner Command-Bot mit discord.py liegt im Leerlauf typischerweise bei einigen zehn Megabyte; ein discord.js-Bot bringt zusätzlich die Node-Laufzeit mit. Der Speicherbedarf wächst mit dem Zustand: Member- und Message-Caches auf großen Servern, Voice und Musik (ein ffmpeg-Prozess pro Stream), Bildgenerierung oder eine Datenbank. In der Praxis betreibt 1 GB RAM bequem das Betriebssystem plus einen kleinen bis mittleren Bot; Voice-lastige Bots oder mehrere Bots auf einer Maschine rechtfertigen 2 GB oder mehr, und ab 2.500 Servern verlangt Discord Sharding, was den Bedarf vervielfacht. Zwei günstige Sicherheitsnetze: MemoryMax=512M in der Unit, damit ein Leck den Bot neu startet statt die Maschine lahmzulegen, und eine kleine Swap-Datei.

All das setzt eine Linux-Maschine mit Root-Zugriff voraus, die rund um die Uhr läuft. Falls Ihnen diese Maschine noch fehlt: der Discord-Bot-VPS von rdp.monster ist rund 10 Sekunden nach Zahlungsbestätigung online, mit dedizierter CPU und dediziertem RAM, vollem Root-Zugriff, unbegrenzter Bandbreite (Fair Use), ohne KYC, mit Krypto-Zahlung, ab $8.99/Monat – damit kann das obige systemctl enable --now mybot das Letzte sein, was Sie tippen, bevor der Bot grün leuchtet.

Häufig gestellte Fragen

Kann ich einen Discord-Bot kostenlos rund um die Uhr hosten?

Zuverlässig nicht mehr: Die Gratis-Tarife, die Bots wach hielten, wurden abgeschafft oder schlafen bei Inaktivität ein.
Heroku hat die kostenlosen Dynos im November 2022 gestrichen, Replit hat Always-on in kostenpflichtige Deployments verlagert und Glitch hat sein App-Hosting 2025 eingestellt. Die verbliebenen kostenlosen Web-Tarife schlafen bei Inaktivität ein, was die Gateway-Verbindung des Bots schließt. Ihn auf dem eigenen PC laufen zu lassen funktioniert, bis der PC neu startet oder in den Ruhezustand geht. Die günstigste verlässliche Option ist ein kleiner VPS mit rund 1 GB RAM, auf dem systemd den Bot nach Absturz und Neustart wieder hochfährt und niemand ihn wegen Leerlauf aussetzt.

Braucht ein Discord-Bot eine feste IP oder offene Ports auf dem VPS?

Nein: Der Bot verbindet sich ausgehend mit Discord, es muss also kein eingehender Port offen sein und die IP spielt keine Rolle.
Ein Gateway-Bot öffnet einen ausgehenden WebSocket zu Discord und empfängt Ereignisse über dieselbe Verbindung; die Firewall auf dem VPS kann also außer SSH alles blockieren, und die IP des Servers wird den Nutzern nie angezeigt. Einen offenen Port und einen öffentlichen Hostnamen brauchen Sie nur, wenn Sie auf HTTP-Interaction-Endpoints umsteigen, die Discord über eine von Ihnen registrierte URL aufruft, oder wenn Sie ein Web-Dashboard ergänzen. Setzen Sie das dann per Reverse Proxy hinter HTTPS.

Kann ich mehrere Discord-Bots auf einem VPS betreiben?

Ja, eine systemd-Unit (oder ein pm2-Prozess) pro Bot, idealerweise jeweils unter eigenem Benutzer und Verzeichnis.
Nichts beschränkt Sie auf einen Bot pro Maschine. Geben Sie jedem Bot ein eigenes Verzeichnis wie /opt/bot-a und /opt/bot-b, eine eigene .env mit eigenem Token und eine eigene Unit-Datei, und führen Sie dann für jeden systemctl enable --now aus. Getrennte Systembenutzer verhindern, dass ein Fehler in einem Bot den Token des anderen lesen kann. Das einzige gemeinsame Budget sind RAM und CPU: Beobachten Sie systemctl status je Unit und wechseln Sie auf einen größeren Tarif, wenn die Summe an die Grenze stößt.

Windows- oder Linux-VPS für einen Discord-Bot?

Linux ist der Standard für Bots: günstiger, schlanker, und das Tooling (systemd, pm2, Docker) ist dafür gemacht.
Sowohl discord.py als auch discord.js laufen unter Windows, und ein Windows-VPS ist die richtige Wahl, wenn der Bot auf eine Windows-only-Anwendung angewiesen ist oder Sie schlicht einen Desktop bevorzugen. Für einen einfachen Bot gewinnt Linux: Das Betriebssystem braucht einen Bruchteil des RAM, ein minimaler Server hat kaum Angriffsfläche, und einen Prozess am Leben zu halten ist eine zehnzeilige systemd-Unit. Unter Windows würden Sie dasselbe Neustartverhalten über den Aufgabenplaner oder NSSM erreichen – mit mehr Klicks.

Adrien Roche, Redakteur für Infrastruktur & Hosting

Systemingenieur mit über 10 Jahren Erfahrung im Betrieb von Windows-Server- und Linux-Flotten. Adrien pflegt die Infrastruktur-Dokumentation von rdp.monster und schreibt unsere Guides zu RDP, VPS-Hosting, Serveradministration, Netzwerken und Privacy-Tools.

Für unser Reseller-Programm registrieren

Ihre Angaben

Wenn Sie Fragen haben, kontaktieren Sie uns hier !
Name(Pflichtfeld)
Geben Sie Ihre E-Mail-Adresse ein. Sie benötigen ein Konto bei manager.rdp.monster !

Ihr Unternehmen

Geben Sie Ihre Website-Adresse ein, falls Sie eine haben
Beschreiben Sie kurz, wie Sie Ihre Dienste an Ihre Kunden verkaufen wollen. Zum Beispiel: Nutzer in Foren ansprechen.

Wir verwenden Cookies!

Wir verwenden Cookies, um Ihr Surferlebnis zu verbessern, personalisierte Anzeigen oder Inhalte anzuzeigen und unseren Traffic zu analysieren. Mit einem Klick auf „Akzeptieren“ stimmen Sie der Nutzung von Cookies zu.