Ouverture commerciale reportée le temps de finaliser nos locaux à Limoges. Être prévenu de l'ouverture

Héberger un bot Discord en Python (discord.py)

Bots et applicatif · 5 min de lecture · Mis à jour le 16 octobre 2026

Ce guide met en ligne un bot écrit avec discord.py 2.x pour qu'il tourne en continu. Le principe est le même qu'en JavaScript : un dépôt Git propre, des dépendances figées, un jeton lu dans l'environnement et un processus relancé automatiquement.

Avant de commencer

Préparer le dépôt

Structure minimale

mon-bot/
├── main.py
├── requirements.txt
├── .gitignore
└── .env.example

requirements.txt

Fixez les versions pour que le serveur installe exactement ce que vous avez testé :

discord.py==2.7.1

Après un pip install en local, pip freeze > requirements.txt produit la liste complète. Supprimez-en les paquets qui ne servent qu'au développement.

main.py

import logging
import os

import discord
from discord import app_commands

logging.basicConfig(level=logging.INFO)

TOKEN = os.environ.get("DISCORD_TOKEN")
if not TOKEN:
    raise SystemExit("DISCORD_TOKEN manquant : le bot ne peut pas démarrer.")

intents = discord.Intents.default()

class MonBot(discord.Client):
    def __init__(self):
        super().__init__(intents=intents)
        self.tree = app_commands.CommandTree(self)

    async def setup_hook(self):
        # Synchronise les commandes slash au démarrage.
        # Sur un gros bot, préférez une synchronisation manuelle.
        await self.tree.sync()

bot = MonBot()

@bot.tree.command(description="Vérifie que le bot répond")
async def ping(interaction: discord.Interaction):
    await interaction.response.send_message("Pong.")

@bot.event
async def on_ready():
    logging.info("Connecté en tant que %s", bot.user)

bot.run(TOKEN, log_handler=None)

log_handler=None évite un double affichage, puisque la journalisation est déjà configurée par logging.basicConfig.

Le jeton hors du dépôt

# .gitignore
__pycache__/
.venv/
.env

En local, gardez le jeton dans .env et chargez-le avec python-dotenv (load_dotenv() en tête de main.py), ou exportez-le dans votre terminal. Le fichier .env.example versionné liste seulement les noms : DISCORD_TOKEN=. Voir Variables d'environnement et jetons.

Option 1 : l'hébergement applicatif

Tout se passe dans la boutique et dans votre espace client.

  1. Commandez la formule Application Starter (1,99 € TTC par mois, jusqu'à 2 Go de RAM et 2 vCPU). Le seul champ à remplir est le nom du projet.
  2. Dans votre espace client, ouvrez le service et cliquez sur « Nouvelle application » : nom, sous-domaine facultatif, Dépôt public (adresse https) ou Mes dépôts GitHub (privés), branche, type de build, port facultatif, et variables d'environnement (une par ligne, NOM=valeur) : ajoutez DISCORD_TOKEN=votre_jeton. Les Options avancées permettent d'imposer les commandes d'installation, de build et de démarrage (par exemple python main.py).
  3. Cliquez sur « Déployer ». Comptez 5 à 15 minutes pour le premier déploiement ; les suivants réutilisent l'environnement mis en cache.
  4. Cliquez sur « Journaux » et contrôlez la ligne Connecté en tant que ….

Si le bot plante, il est relancé automatiquement. Les boutons « Redémarrer », « Arrêter » et « Redéployer » restent à votre main, et un encadré « Pourquoi ça a échoué » résume la cause d'un déploiement raté. Pour changer le jeton, cliquez sur « Variables », modifiez la ligne, « Enregistrer », puis « Redéployer » : les variables s'appliquent au prochain redéploiement.

Le type de build Automatique (détecté dans le dépôt) reconnaît le langage du projet. Pour ne rien laisser au hasard, choisissez Dockerfile et ajoutez ce fichier à la racine :

FROM python:3.12-slim
ENV PYTHONUNBUFFERED=1
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "main.py"]

PYTHONUNBUFFERED=1 fait apparaître les messages dans les journaux au moment où ils sont écrits, et non par paquets.

Option 2 : sur un VPS

Sur un VPS Debian, travaillez dans un environnement virtuel pour ne pas mélanger les paquets du bot avec ceux du système :

apt install -y python3-venv git
adduser --system --group --home /opt/mon-bot bot
git clone https://exemple.org/vous/mon-bot.git /opt/mon-bot
python3 -m venv /opt/mon-bot/.venv
/opt/mon-bot/.venv/bin/pip install -r /opt/mon-bot/requirements.txt
install -m 600 -o root -g root /dev/null /etc/mon-bot.env
nano /etc/mon-bot.env      # DISCORD_TOKEN=...
chown -R bot:bot /opt/mon-bot
# /etc/systemd/system/mon-bot.service
[Unit]
Description=Bot Discord (Python)
After=network-online.target
Wants=network-online.target

[Service]
User=bot
WorkingDirectory=/opt/mon-bot
EnvironmentFile=/etc/mon-bot.env
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/mon-bot/.venv/bin/python main.py
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now mon-bot
journalctl -u mon-bot -f

Séquence vérifiée sur un VPS conteneur et sur un VPS machine virtuelle Debian 13 (Python 3.13.5) : venv, installation des dépendances, unité systemd, démarrage. Avec un jeton invalide, le service échoue proprement (discord.errors.LoginFailure, code de sortie 1) et systemd le relance toutes les 5 secondes ; le service démarre de lui-même après un redémarrage.

Attention à la version de discord.py : sur Debian 13 (Python 3.13), la version 2.4.0 ne démarre pas (ModuleNotFoundError: No module named 'audioop'). Utilisez une version récente, 2.7.1 ici, qui installe automatiquement le paquet audioop-lts. Pour connaître les versions disponibles : pip index versions discord.py.

Mettre à jour

Problèmes fréquents

Symptôme Cause probable
discord.errors.LoginFailure: Improper token Jeton absent, tronqué ou régénéré.
PrivilegedIntentsRequired Intent demandé dans le code mais non coché sur le portail.
Aucun message dans les journaux Sortie mise en tampon : ajoutez PYTHONUNBUFFERED=1 (dans le Dockerfile, ou dans « Variables » sur l'applicatif).
ModuleNotFoundError Paquet absent de requirements.txt.
Commandes slash absentes tree.sync() non appelé, ou délai de propagation des commandes globales.

Besoin d'aide ?

Ouvrez un ticket depuis votre espace client avec le nom de l'application et le message d'erreur. Ne communiquez jamais votre jeton.

Retour à la documentation