RDP Monster

Héberger un bot Discord sur un VPS : en ligne 24/7

Héberger un bot Discord sur un VPS : en ligne 24/7

Pourquoi c'est sur un VPS que les bots Discord restent vraiment en ligne

Un bot Discord n'est pas une page web. Une fois connecté, il maintient une connexion WebSocket persistante vers la passerelle de Discord et doit répondre aux heartbeats en continu ; dès que le processus s'arrête, le bot apparaît hors ligne et toutes les commandes échouent. Cette seule exigence, un processus qui ne dort jamais, élimine la plupart des hébergements « gratuits » :

  • Heroku a supprimé ses dynos gratuits en novembre 2022.
  • Replit ne maintient plus les projets gratuits en fonctionnement ; l'always-on est passé aux déploiements payants.
  • Glitch a mis fin à son hébergement d'applications en 2025.
  • Les offres web gratuites qui se mettent en veille après inactivité coupent la connexion à la passerelle à chaque fois ; pour les utilisateurs, ce bot est tout simplement hors service.

L'hébergement d'un bot Discord sur un VPS règle le problème à la racine : une machine Linux avec accès root qui tourne en permanence, où le bot n'est qu'un service de plus géré par le système d'init. Ce guide met tout cela en place sur Ubuntu 24.04 (valable aussi pour 22.04 et Debian 12) avec discord.py et discord.js, puis traite la gestion du token, les redémarrages, les logs, les mises à jour et la mémoire.

Préparer le VPS : un utilisateur dédié et un runtime

Sécurisez d'abord la porte d'entrée : activez SSH sur Ubuntu et durcissez-le avec l'authentification par clé, sans connexion root, et ufw. Un bot se connecte vers l'extérieur à Discord et n'a besoin d'aucun port entrant : le pare-feu peut rester fermé à tout sauf SSH.

Étape 1 : créer un compte non privilégié pour le bot

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

Un compte dédié fait qu'un bot bogué ou une dépendance npm ou PyPI compromise ne peut pas lire vos clés SSH ni toucher aux autres services. Tout vit dans /opt/mybot, propriété de bot.

Étape 2 (Python) : installer discord.py dans un environnement virtuel

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 exige Python 3.8 ou plus récent ; Ubuntu 24.04 fournit 3.12 et 22.04 fournit 3.10, l'interpréteur de la distribution convient donc. N'ajoutez discord.py[voice] et ffmpeg que pour les salons vocaux.

Étape 3 (Node.js) : installer une LTS récente et discord.js

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'

Le paquet nodejs d'Ubuntu est très en retard sur l'amont et discord.js v14 réclame un runtime moderne : utilisez NodeSource (ci-dessus) ou nvm pour une LTS récente. Avec nvm, lancez which node et utilisez ce chemin absolu dans l'unité de service.

Garder le token hors du code : le fichier .env

Le token du bot est un mot de passe qui donne le contrôle total du bot : ne le collez jamais dans bot.py ni index.js, ne le committez jamais. Mettez-le dans /opt/mybot/.env, lisible uniquement par le compte du bot, à l'aide d'un éditeur plutôt que d'echo, car un token tapé en ligne de commande atterrit dans l'historique du shell :

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

Le format est une paire KEY=value par ligne, sans guillemets ni export. python-dotenv et le paquet npm dotenv le lisent, et systemd peut injecter le même fichier avec EnvironmentFile= (section suivante) ; combiner les deux est sans risque, aucune des deux bibliothèques n'écrasant une variable déjà définie. Si le token fuite un jour, réinitialisez-le immédiatement dans le Developer Portal sous Bot → Reset Token.

Un bot minimal en discord.py et en discord.js

Les deux exemples lisent le token depuis l'environnement, activent l'intent Message Content et répondent à !ping. Dans le Developer Portal, créez une application, ajoutez un utilisateur bot, copiez le token (affiché une seule fois), activez Message Content Intent sous Bot → Privileged Gateway Intents, puis invitez le bot sur un serveur de test via le générateur d'URL OAuth2 avec le scope bot.

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);

Lancez-le une fois au premier plan : sudo -u bot /opt/mybot/.venv/bin/python /opt/mybot/bot.py ou sudo -u bot node /opt/mybot/index.js, attendez Logged in as, envoyez !ping, puis Ctrl-C. À ce stade, le bot ne vit que le temps de votre session SSH : fermer le terminal envoie SIGHUP à ses processus enfants et le bot meurt.

Le faire tourner sous systemd avec Restart=always

systemd est déjà le système d'init d'Ubuntu : la façon la plus propre de garder le bot en ligne après une déconnexion, un plantage ou un redémarrage est une unité de service, sans démon supplémentaire, avec des logs qui atterrissent dans le journal.

Étape 1 : écrire l'unité

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

Pour discord.js, mettez ExecStart=/usr/bin/node /opt/mybot/index.js et supprimez la ligne PYTHONUNBUFFERED. Les directives qui comptent :

  • Restart=always relance le processus à chaque sortie, plantage ou sys.exit() propre indifféremment ; RestartSec=5 évite qu'un bot qui meurt instantanément (mauvais token, erreur de syntaxe) ne boucle à toute vitesse.
  • Wants=/After=network-online.target retardent le démarrage jusqu'à ce que le réseau soit prêt, pour que la première connexion après un redémarrage n'échoue pas sur le DNS.
  • PYTHONUNBUFFERED=1 : sans terminal, Python bufferise stdout par blocs et les lignes print() arrivent dans le journal avec plusieurs minutes de retard, ou seulement à la sortie.
  • Les lignes Protect*, PrivateTmp et NoNewPrivileges rendent le reste du système de fichiers en lecture seule ou invisible pour le bot ; ajoutez tout répertoire où il doit écrire à ReadWritePaths=.

Étape 2 : activer, démarrer et vérifier

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 crée le lien symbolique de démarrage et --now lance l'unité. La ligne kill est le vrai test : si systemctl status mybot affiche active (running) quelques secondes plus tard, la politique de redémarrage fonctionne, et un sudo reboot valide le chemin de démarrage. Pour le voir aux côtés de tous les autres services, listez les services en cours avec systemctl ; il apparaît comme mybot.service, et systemctl is-enabled mybot confirme qu'il reviendra après un redémarrage.

Alternative : pm2, et comparaison avec screen, nohup et Docker

Chaque façon de garder un bot en vie répond à trois questions : survit-elle à la déconnexion SSH, redémarre-t-elle après un plantage, démarre-t-elle au boot ?

MéthodeSurvit à la déconnexion SSHRedémarre après un plantageDémarre au bootVerdict
nohup / &OuiNonNonTests rapides uniquement.
screen / tmuxOuiNonNon, sauf script dédiéDébogage, pas production.
pm2OuiOuiOui, après pm2 startup + pm2 saveBon pour les équipes Node.js ; une seule CLI pour les logs et les redémarrages.
unité systemdOuiOui (Restart=)Oui (enable)Recommandé ; aucun logiciel supplémentaire, durcissement intégré.
Docker, restart: unless-stoppedOuiOuiOui, avec le démon DockerBon quand le bot est déjà livré sous forme d'image.

pm2 est le choix populaire dans le monde Node.js et gère aussi Python. Lancez-le sous le compte propriétaire du bot :

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 génère une unité systemd pm2-<user> qui ressuscite au boot la liste de processus enregistrée : pm2 s'appuie donc sur systemd plutôt que de le remplacer, ce qui est l'argument honnête pour utiliser directement systemd pour un bot unique. pm2 justifie sa place avec plusieurs processus Node ou une équipe qui le connaît déjà.

Si vous préférez les conteneurs, l'équivalent est restart: unless-stopped dans un fichier Compose ; le tutoriel pour installer Docker sur un VPS Ubuntu couvre le moteur, Compose et le comportement au démarrage. Sa mise en garde sur ufw ne concerne pas un bot, qui ne publie aucun port.

Logs, mises à jour et dimensionnement mémoire

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 effectue la rotation et la compression tout seul. Si le bot écrit son propre fichier de log, utilisez logging.handlers.RotatingFileHandler en Python ou un transport rotatif avec pino ou winston en Node, pour qu'un handler bavard ne puisse pas remplir le disque.

Mises à jour

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

Un redémarrage coupe la connexion à la passerelle quelques secondes ; la bibliothèque se reconnecte et les utilisateurs le remarquent rarement. Figez les versions des bibliothèques dans requirements.txt ou package-lock.json et lisez le changelog avant une montée de version majeure. Gardez l'OS à jour avec sudo apt update && sudo apt upgrade ou unattended-upgrades.

Combien de RAM faut-il au bot ?

Ne dimensionnez pas à partir de chiffres génériques : mesurez. systemctl status mybot affiche une ligne Memory: et pm2 list montre la même chose. Un bot discord.py à commandes seules consomme typiquement quelques dizaines de mégaoctets au repos ; un bot discord.js porte en plus le runtime Node. La mémoire augmente avec l'état : caches de membres et de messages sur les gros serveurs, voix et musique (un processus ffmpeg par flux), génération d'images ou base de données. En pratique, 1 Go de RAM fait tourner confortablement l'OS plus un bot petit ou moyen ; les bots très axés voix ou plusieurs bots sur une même machine justifient 2 Go ou plus, et au-delà de 2 500 serveurs Discord impose le sharding, qui multiplie l'empreinte. Deux filets de sécurité peu coûteux : MemoryMax=512M dans l'unité, pour qu'une fuite redémarre le bot au lieu de faire tomber la machine, et un petit fichier d'échange.

Tout cela suppose une machine Linux avec accès root qui reste allumée en permanence. S'il vous manque encore cette machine, le VPS pour bot Discord de rdp.monster est en ligne environ 10 secondes après confirmation du paiement, avec CPU et RAM dédiés, accès root complet, bande passante illimitée (fair-use), sans KYC, crypto acceptée, à partir de $8.99/mois, de sorte que l'étape systemctl enable --now mybot ci-dessus peut être la dernière chose que vous tapez avant que le bot ne passe au vert.

Foire aux questions

Peut-on héberger un bot Discord gratuitement 24/7 ?

Plus de façon fiable : les offres gratuites qui maintenaient les bots éveillés ont été supprimées ou se mettent désormais en veille en cas d'inactivité.
Heroku a abandonné les dynos gratuits en novembre 2022, Replit a basculé l'always-on vers des déploiements payants, et Glitch a mis fin à l'hébergement d'applications en 2025. Les offres web gratuites restantes se mettent en veille après inactivité, ce qui ferme la connexion du bot à la passerelle. Le faire tourner sur votre PC fonctionne jusqu'à ce que le PC redémarre ou se mette en veille. L'option fiable la moins chère est un petit VPS avec environ 1 Go de RAM, où systemd relance le bot après un plantage ou un redémarrage et où personne ne le suspend parce qu'il est inactif.

Un bot Discord a-t-il besoin d'une IP fixe ou de ports ouverts sur le VPS ?

Non : le bot se connecte vers l'extérieur à Discord, aucun port entrant n'a besoin d'être ouvert et l'IP importe peu.
Un bot passerelle ouvre un WebSocket sortant vers Discord et reçoit les événements par cette même connexion : le pare-feu du VPS peut rester fermé à tout sauf SSH, et l'IP du serveur n'apparaît jamais aux utilisateurs. Vous n'avez besoin d'un port ouvert et d'un nom d'hôte public que si vous passez aux endpoints d'interactions HTTP, que Discord appelle via une URL que vous enregistrez, ou si vous ajoutez un tableau de bord web. Dans ce cas, placez-le derrière du HTTPS avec un reverse proxy.

Peut-on faire tourner plusieurs bots Discord sur un seul VPS ?

Oui : une unité systemd (ou un processus pm2) par bot, idéalement chacun sous son propre utilisateur et son propre répertoire.
Rien ne vous limite à un bot par machine. Donnez à chaque bot son répertoire, par exemple /opt/bot-a et /opt/bot-b, son propre .env avec son propre token et son propre fichier d'unité, puis faites systemctl enable --now sur chacun. Des utilisateurs système distincts empêchent qu'un bug dans un bot ne lise le token de l'autre. Le seul budget partagé est la RAM et le CPU : surveillez systemctl status pour chaque unité et passez à une offre plus grande quand le total approche la limite.

Faut-il héberger un bot Discord sur un VPS Windows ou Linux ?

Linux est le choix par défaut pour les bots : moins cher, plus léger, et l'outillage (systemd, pm2, Docker) est fait pour lui.
discord.py et discord.js tournent tous deux sous Windows, et un VPS Windows est le bon choix si le bot dépend d'une application uniquement Windows ou si vous préférez simplement un bureau graphique. Pour un bot classique, Linux l'emporte : l'OS utilise une fraction de la RAM, un serveur minimal n'a presque aucune surface d'attaque, et maintenir un processus en vie tient en une unité systemd de dix lignes. Sous Windows, il faudrait le Planificateur de tâches ou NSSM pour obtenir le même redémarrage au boot, avec plus de clics.

Adrien Roche, Rédacteur infrastructure & hébergement

Ingénieur systèmes avec plus de 10 ans d'exploitation de parcs Windows Server et Linux. Adrien gère la documentation infrastructure de rdp.monster et rédige nos guides sur le RDP, l'hébergement VPS, l'administration serveur, le réseau et les outils de confidentialité.

Inscrivez-vous à notre programme revendeur

Vos informations

Si vous avez une question, contactez-nous en cliquant ici !
Nom(Obligatoire)
Indiquez votre adresse e-mail, vous devez avoir un compte sur manager.rdp.monster !

Votre entreprise

Indiquez l'adresse de votre site web si vous en avez un
Expliquez brièvement comment vous comptez vendre les services à vos clients. Par exemple, en discutant avec des gens sur des forums.

Même les monstres aiment les cookies !

Nous utilisons des cookies pour améliorer votre expérience de navigation, proposer des publicités ou contenus personnalisés et analyser notre trafic. En cliquant sur « Accepter », vous consentez à notre utilisation des cookies.