RDP Monster

Hosting di un bot Discord su VPS: online 24/7

Hosting di un bot Discord su VPS: online 24/7

Perché su un VPS i bot Discord restano davvero online

Un bot Discord non è una pagina web. Una volta effettuato il login mantiene una connessione WebSocket persistente al gateway di Discord e deve rispondere agli heartbeat di continuo; quando il processo si ferma, il bot risulta offline e ogni comando fallisce. Questo singolo requisito, un processo che non dorme mai, esclude quasi tutto l'hosting «gratuito»:

  • Heroku ha rimosso i dyno gratuiti a novembre 2022.
  • Replit non tiene più in esecuzione i progetti gratuiti; la modalità always-on è passata ai deployment a pagamento.
  • Glitch ha chiuso l'hosting delle app nel 2025.
  • I piani web gratuiti che si sospendono dopo un periodo di inattività interrompono la connessione al gateway a ogni pausa; per gli utenti quel bot è semplicemente offline.

L'hosting di un bot Discord su VPS risolve il problema alla radice: una macchina Linux con accesso root attiva 24 ore su 24, dove il bot è solo un altro servizio gestito dal sistema di init. Questa guida lo realizza su Ubuntu 24.04 (valida anche per 22.04 e Debian 12) con discord.py e discord.js, poi affronta gestione del token, riavvii, log, aggiornamenti e memoria.

Preparare il VPS: un utente dedicato e un runtime

Prima di tutto metti in sicurezza la porta d'ingresso: attiva SSH su Ubuntu e mettilo in sicurezza con autenticazione a chiave, login root disabilitato e ufw. Un bot apre connessioni verso Discord e non ha bisogno di porte in ingresso, quindi il firewall può restare chiuso a tutto tranne che a SSH.

Passo 1: creare un account senza privilegi per il bot

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

Un account dedicato fa sì che un bot pieno di bug o una dipendenza npm o PyPI compromessa non possa leggere le tue chiavi SSH né toccare altri servizi. Tutto risiede in /opt/mybot, di proprietà di bot.

Passo 2 (Python): installare discord.py in un ambiente virtuale

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 richiede Python 3.8 o superiore; Ubuntu 24.04 include la 3.12 e la 22.04 la 3.10, quindi l'interprete della distribuzione va bene. Aggiungi discord.py[voice] e ffmpeg solo per i canali vocali.

Passo 3 (Node.js): installare una LTS aggiornata e 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'

Il pacchetto nodejs di Ubuntu è parecchio indietro rispetto all'upstream e discord.js v14 richiede un runtime moderno, quindi usa NodeSource (sopra) o nvm per una LTS aggiornata. Con nvm, esegui which node e usa quel percorso assoluto nell'unit del servizio.

Tenere il token fuori dal codice: il file .env

Il token del bot è una password con pieno controllo sul bot: non incollarlo mai in bot.py o index.js e non committarlo mai. Mettilo in /opt/mybot/.env, leggibile solo dall'account del bot, usando un editor invece di echo, perché un token digitato sulla riga di comando finisce nella cronologia della 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

Il formato prevede una coppia KEY=value per riga, senza virgolette e senza export. python-dotenv e il pacchetto npm dotenv lo leggono, e systemd può iniettare lo stesso file con EnvironmentFile= (sezione successiva); combinarli non crea problemi, perché nessuna delle due librerie sovrascrive una variabile già esistente. Se il token dovesse trapelare, rigeneralo subito nel Developer Portal sotto Bot → Reset Token.

Un bot minimale in discord.py e discord.js

Entrambi gli esempi leggono il token dall'ambiente, abilitano l'intent Message Content e rispondono a !ping. Nel Developer Portal crea un'applicazione, aggiungi un utente bot, copia il token (mostrato una sola volta), abilita Message Content Intent sotto Bot → Privileged Gateway Intents e invita il bot in un server di prova tramite il generatore di URL OAuth2 con lo 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);

Eseguilo una volta in primo piano: sudo -u bot /opt/mybot/.venv/bin/python /opt/mybot/bot.py oppure sudo -u bot node /opt/mybot/index.js, attendi Logged in as, invia !ping, poi premi Ctrl-C. Per ora il bot vive solo quanto la tua sessione SSH: chiudendo il terminale viene inviato SIGHUP ai processi figli e il bot muore.

Eseguirlo con systemd e Restart=always

systemd è già il sistema di init di Ubuntu, quindi il modo più pulito per tenere il bot online dopo logout, crash e riavvio è un unit di servizio: nessun demone aggiuntivo e i log finiscono nel journal.

Passo 1: scrivere 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

Per discord.js, imposta ExecStart=/usr/bin/node /opt/mybot/index.js ed elimina la riga PYTHONUNBUFFERED. Le direttive che contano:

  • Restart=always riavvia il processo a ogni uscita, sia un crash sia un sys.exit() pulito; RestartSec=5 evita che un bot che muore all'istante (token errato, errore di sintassi) entri in un ciclo serrato.
  • Wants=/After=network-online.target ritardano l'avvio finché la rete non è pronta, così il primo login dopo un riavvio non fallisce sul DNS.
  • PYTHONUNBUFFERED=1: senza un terminale Python usa il buffering a blocchi su stdout e le righe di print() arrivano nel journal con minuti di ritardo o solo all'uscita.
  • Le righe Protect*, PrivateTmp e NoNewPrivileges rendono il resto del filesystem in sola lettura o invisibile al bot; aggiungi a ReadWritePaths= ogni directory su cui deve scrivere.

Passo 2: abilitare, avviare e verificare

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 crea il collegamento simbolico di avvio e --now fa partire l'unit. La riga con kill è la vera prova: se qualche secondo dopo systemctl status mybot mostra active (running), la politica di riavvio funziona, e un sudo reboot conferma il percorso di boot. Per vederlo insieme a tutti gli altri servizi, elenca i servizi attivi con systemctl; compare come mybot.service, e systemctl is-enabled mybot conferma che tornerà dopo un riavvio.

Alternativa: pm2, e il confronto con screen, nohup e Docker

Ogni modo di tenere vivo un bot risponde a tre domande: sopravvive alla disconnessione SSH, si riavvia dopo un crash e parte al boot?

MetodoSopravvive al logout SSHSi riavvia dopo un crashParte al riavvioVerdetto
nohup / &SìNoNoSolo per test rapidi.
screen / tmuxSìNoNo, se non con uno scriptDebug, non produzione.
pm2SìSìSì, dopo pm2 startup + pm2 saveOttimo per i team Node.js; una sola CLI per log e riavvii.
unit systemdSìSì (Restart=)Sì (enable)Consigliato; nessun software extra, hardening integrato.
Docker, restart: unless-stoppedSìSìSì, con il demone DockerOttimo quando il bot è già distribuito come immagine.

pm2 è la scelta popolare nel mondo Node.js e gestisce anche Python. Eseguilo come l'account proprietario del 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 genera un unit systemd pm2-<user> che ripristina al boot la lista dei processi salvata, quindi pm2 sta sopra systemd invece di sostituirlo: è l'argomento onesto per usare direttamente systemd con un solo bot. pm2 si giustifica con diversi processi Node o con un team che già lo conosce.

Se preferisci i container, l'equivalente è restart: unless-stopped in un file Compose; la guida per installare Docker su un VPS Ubuntu copre il motore, Compose e il comportamento all'avvio. Il suo avvertimento su ufw non riguarda un bot, che non pubblica porte.

Log, aggiornamenti e dimensionamento della memoria

Log

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 ruota e comprime da solo. Se il bot scrive un proprio file di log, usa logging.handlers.RotatingFileHandler in Python o un transport rotativo con pino o winston in Node, così un handler troppo loquace non può riempire il disco.

Aggiornamenti

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 riavvio interrompe la connessione al gateway per qualche secondo; la libreria si riconnette e gli utenti raramente se ne accorgono. Fissa le versioni delle librerie in requirements.txt o package-lock.json e leggi il changelog prima di un aggiornamento major. Mantieni aggiornato il sistema con sudo apt update && sudo apt upgrade o unattended-upgrades.

Quanta RAM serve al bot?

Non dimensionare in base a numeri generici: misura. systemctl status mybot stampa una riga Memory: e pm2 list mostra lo stesso dato. Un bot discord.py con soli comandi resta di norma su qualche decina di megabyte a riposo; un bot discord.js aggiunge il runtime Node. La memoria cresce con lo stato: cache di membri e messaggi su server grandi, voce e musica (un processo ffmpeg per stream), generazione di immagini o un database. In pratica 1 GB di RAM fa girare comodamente il sistema più un bot piccolo o medio; bot con molto traffico vocale o più bot sulla stessa macchina giustificano 2 GB o più, e oltre i 2.500 server Discord richiede lo sharding, che moltiplica l'impronta. Due reti di sicurezza a basso costo: MemoryMax=512M nell'unit, così una perdita di memoria riavvia il bot invece di mettere giù la macchina, e un piccolo file di swap.

Tutto questo presuppone una macchina Linux con accesso root attiva 24 ore su 24. Se questa macchina ti manca ancora, il VPS per bot Discord di rdp.monster è online circa 10 secondi dopo la conferma del pagamento, con CPU e RAM dedicate, accesso root completo, banda illimitata (fair-use), senza KYC, cripto accettate, da $8.99/mese, così il passaggio systemctl enable --now mybot visto sopra può essere l'ultima cosa che digiti prima che il bot diventi verde.

Domande frequenti

Posso ospitare un bot Discord gratis 24/7?

Non più in modo affidabile: i piani gratuiti che tenevano svegli i bot sono stati rimossi o oggi si sospendono per inattività.
Heroku ha eliminato i dyno gratuiti a novembre 2022, Replit ha spostato l'always-on sui deployment a pagamento e Glitch ha chiuso l'hosting delle app nel 2025. I piani web gratuiti rimasti si sospendono dopo un periodo di inattività, il che chiude la connessione del bot al gateway. Farlo girare sul tuo PC funziona finché il PC non si riavvia o non va in sospensione. L'opzione affidabile più economica è un piccolo VPS con circa 1 GB di RAM, dove systemd riavvia il bot dopo crash e riavvii e nessuno lo sospende perché è inattivo.

Un bot Discord ha bisogno di un IP statico o di porte aperte sul VPS?

No: il bot si connette in uscita verso Discord, quindi non serve alcuna porta in ingresso e l'IP non ha importanza.
Un bot gateway apre un WebSocket in uscita verso Discord e riceve gli eventi sulla stessa connessione, quindi il firewall del VPS può restare chiuso a tutto tranne che a SSH e l'IP del server non è mai visibile agli utenti. Ti servono una porta aperta e un hostname pubblico solo se passi agli endpoint di interazione HTTP, che Discord chiama tramite un URL che registri tu, oppure se aggiungi una dashboard web. In quel caso mettila dietro HTTPS con un reverse proxy.

Posso eseguire più bot Discord su un solo VPS?

Sì, un unit systemd (o un processo pm2) per bot, idealmente ciascuno con il proprio utente e la propria directory.
Nulla ti limita a un bot per macchina. Dai a ogni bot la sua directory, per esempio /opt/bot-a e /opt/bot-b, il suo .env con il suo token e il suo file unit, poi esegui systemctl enable --now per ciascuno. Utenti di sistema separati impediscono che un bug in un bot legga il token dell'altro. L'unico budget condiviso sono RAM e CPU: controlla systemctl status per ogni unit e passa a un piano più grande quando il totale si avvicina al limite.

Meglio ospitare un bot Discord su un VPS Windows o Linux?

Linux è la scelta predefinita per i bot: più economico, più leggero, e gli strumenti (systemd, pm2, Docker) sono pensati per lui.
Sia discord.py sia discord.js girano su Windows, e un VPS Windows è la scelta giusta se il bot dipende da un'applicazione solo per Windows o se preferisci semplicemente un desktop. Per un bot normale vince Linux: il sistema usa una frazione della RAM, un server minimale ha una superficie d'attacco quasi nulla e tenere vivo un processo è un unit systemd di dieci righe. Su Windows useresti l'Utilità di pianificazione o NSSM per ottenere lo stesso riavvio automatico al boot, con più clic.

Adrien Roche, Editor infrastruttura e hosting

Ingegnere di sistemi con oltre 10 anni di esperienza su parchi server Windows Server e Linux. Adrien cura la documentazione dell'infrastruttura di rdp.monster e scrive le nostre guide su RDP, hosting VPS, amministrazione server, networking e strumenti per la privacy.

Iscriviti al nostro programma rivenditori

I tuoi dati

Se hai domande, contattaci cliccando qui !
Nome completo(Obbligatorio)
Inserisci la tua email: ti serve un account su manager.rdp.monster !

La tua azienda

Inserisci l'indirizzo del tuo sito web, se ne hai uno
Spiegaci in due righe come venderai i servizi ai tuoi clienti. Per esempio, parlandone sui forum.

Anche i mostri adorano i cookie!

Usiamo i cookie per migliorare la tua navigazione, mostrarti annunci o contenuti personalizzati e analizzare il nostro traffico. Cliccando su «Accetta» acconsenti all'uso dei cookie.