Guide 1 · Bots Discord · Production · Équipe Studio Network

Architecture et déploiement d'un Bot Discord moderne en production

Ce guide documente la méthode exacte appliquée à nos bots — dont Kurotsuki Studio — pour passer d'un prototype à un service exploité 24/7 : choix des intents, structuration du code, sharding, conteneurisation Docker et supervision par PM2. Public visé : développeurs Node.js ayant déjà manipulé Discord.js et souhaitant industrialiser leur bot.

Un bot Discord qui dépasse le stade du prototype doit être pensé comme un service distribué : connexion résiliente à la passerelle Discord, séparation stricte entre la logique métier et la couche transport, et supervision du cycle de vie des processus. Avec Discord.js v14, la première décision structurante concerne les Gateway Intents : ne souscrivez qu'aux intents strictement nécessaires (par exemple Guilds, GuildMembers et GuildMessages si la modération l'exige) afin de réduire la surface mémoire et de rester conforme au principe du moindre privilège. Les intents privilégiés se déclarent explicitement dans le portail développeur et doivent être justifiés fonctionnellement.

Structurer le code : commandes, événements et services

Organisez le projet en trois couches. La couche transport (client Discord.js, enregistrement des slash commands, gestionnaires d'événements) ne contient aucune règle métier. La couche services expose des fonctions pures et testables (modération, planification, persistance). La couche infrastructure regroupe la configuration, les clients base de données et les files d'attente. Les commandes slash sont enregistrées via l'API REST de Discord au déploiement, jamais à chaque démarrage, afin d'éviter les limites de taux. Stockez les identifiants d'application et les tokens exclusivement dans des variables d'environnement injectées au runtime.

Sharding et cycle de vie des processus

Au-delà d'environ 2 500 guildes, Discord impose le sharding : la charge de la passerelle est répartie sur plusieurs processus (shards) coordonnés par un gestionnaire. Prévoyez dès le départ un ShardingManager qui surveille les redémarrages, propage les arrêts gracieux (SIGTERM) et répercute les variables d'environnement à chaque shard. Chaque shard expose une sonde de santé locale (statut de connexion, latence heartbeat, nombre de guildes) remontée vers le superviseur. Un arrêt gracieux ferme les connexions base de données, termine les tâches planifiées en cours et confirme la fin du traitement avant de quitter : c'est ce qui évite les doubles réponses et les états corrompus lors des mises à jour.

Conteneurisation et PM2 : une stratégie de déploiement reproductible

En production, figez les dépendances avec un package-lock.json versionné et construisez une image Docker minimale (base Node.js LTS slim, utilisateur non-root, healthcheck HTTP). Pour les hôtes Linux classiques sans orchestrateur, PM2 reste un gestionnaire de processus robuste : redémarrage automatique, mode cluster pour les workers stateless, rotation des journaux et démarrage au boot via pm2 startup. La configuration ci-dessous illustre un déploiement canonique avec variables d'environnement séparées par environnement :

// ecosystem.config.js — déploiement PM2 du bot et de son shard manager
module.exports = {
  apps: [{
    name: "kurotsuki-shards",
    script: "./src/shard-manager.js",
    instances: 1,
    exec_mode: "fork",
    watch: false,
    max_memory_restart: "512M",
    restart_delay: 5000,
    exp_backoff_restart_delay: 100,
    env_production: {
      NODE_ENV: "production",
      DISCORD_TOKEN: process.env.DISCORD_TOKEN,
      DATABASE_URL: process.env.DATABASE_URL,
      LOG_LEVEL: "info"
    }
  }]
};
# Dockerfile minimal — image reproductible, utilisateur non-root
FROM node:20-bookworm-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY src ./src
RUN useradd -r bot && chown -R bot:bot /app
USER bot
HEALTHCHECK --interval=30s --timeout=5s CMD node ./src/healthcheck.js
CMD ["node", "./src/shard-manager.js"]
Checklist de mise en production : intents minimaux déclarés, commandes slash enregistrées au déploiement, secrets hors du dépôt, healthcheck exposé, journaux centralisés avec identifiant de shard, sauvegardes de la base avant chaque migration, et procédure de rollback testée.

Tests, charge et exploitation courante

Avant chaque mise en production, exécutez les tests unitaires des services, un test de contrat sur l'enregistrement des commandes et un test de charge modéré sur les routes les plus sollicitées (statuts, classements, modération). En exploitation, surveillez la latence du heartbeat de la passerelle, la taille des files d'événements et la consommation mémoire par shard : une dérive lente signale généralement une fuite (écouteurs non retirés, temporisateurs oubliés) plutôt qu'un pic de trafic. Versionnez chaque image Docker par commit, conservez les trois dernières versions déployables et documentez la procédure de retour arrière afin qu'un rollback reste une opération d'une commande, même en pleine soirée d'activité communautaire.

À retenir

Un bot fiable en production repose sur trois piliers : des intents minimaux et justifiés, une séparation stricte transport / services / infrastructure, et un cycle de vie supervisé (sharding, arrêts gracieux, healthchecks, rollback versionné). Une fois le bot stable, sécurisez ses points d'entrée externes — webhooks et clés d'API — en suivant notre guide 2 sur la sécurisation des webhooks, puis fiabilisez l'hébergement global avec le guide 3 sur l'infrastructure Node.js & Next.js.