Hospedar um bot do Discord num VPS 24/7
- 18 de outubro de 2026
- 09:00
- Por Adrien Roche
- Tutoriais

Porque é num VPS que os bots do Discord ficam mesmo online
Um bot do Discord não é uma página web. Depois de autenticado, mantém uma ligação WebSocket persistente ao gateway do Discord e tem de responder continuamente aos heartbeats; quando o processo para, o bot aparece offline e todos os comandos falham. Esse requisito único, um processo que nunca dorme, exclui a maior parte do alojamento «gratuito»:
- Heroku retirou os dynos gratuitos em novembro de 2022.
- Replit deixou de manter projetos gratuitos em execução; o modo always-on passou para as implementações pagas.
- Glitch terminou o alojamento de aplicações em 2025.
- Os planos web gratuitos que adormecem após inatividade cortam a ligação ao gateway sempre que ficam parados; para os utilizadores, esse bot está simplesmente em baixo.
Hospedar o bot do Discord num VPS resolve o problema na raiz: uma máquina Linux com acesso root que funciona 24 horas por dia, onde o bot é apenas mais um serviço gerido pelo sistema de init. Este guia mostra como o fazer no Ubuntu 24.04 (válido também para 22.04 e Debian 12) com discord.py e discord.js, e depois aborda a gestão do token, os reinícios, os logs, as atualizações e a memória.
Preparar o VPS: um utilizador dedicado e um runtime
Comece por proteger a porta de entrada: ative o SSH no Ubuntu e reforce-o com autenticação por chave, sem login de root e com ufw. Um bot liga-se para fora, ao Discord, e não precisa de portas de entrada, pelo que a firewall pode ficar fechada a tudo menos ao SSH.
Passo 1: criar uma conta sem privilégios para o bot
sudo useradd -r -m -d /opt/mybot -s /usr/sbin/nologin bot
Uma conta dedicada garante que um bot com bugs ou uma dependência npm ou PyPI comprometida não consegue ler as suas chaves SSH nem mexer noutros serviços. Tudo fica em /opt/mybot, propriedade de bot.
Passo 2 (Python): instalar discord.py num ambiente virtual
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
O discord.py 2.x requer Python 3.8 ou superior; o Ubuntu 24.04 inclui o 3.12 e o 22.04 o 3.10, por isso o interpretador da distribuição serve. Acrescente discord.py[voice] e ffmpeg apenas para canais de voz.
Passo 3 (Node.js): instalar uma LTS atual e o 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'
O pacote nodejs do próprio Ubuntu está bastante atrasado face ao upstream e o discord.js v14 exige um runtime moderno, por isso use o NodeSource (acima) ou o nvm para obter uma LTS atual. Com o nvm, execute which node e use esse caminho absoluto na unidade de serviço.
Manter o token fora do código: o ficheiro .env
O token do bot é uma palavra-passe com controlo total sobre o bot: nunca o cole em bot.py ou index.js, nunca o envie para o repositório. Coloque-o em /opt/mybot/.env, legível apenas pela conta do bot, usando um editor em vez de echo, já que um token escrito na linha de comandos fica no histórico da 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
O formato é um KEY=value por linha, sem aspas e sem export. O python-dotenv e o pacote npm dotenv leem-no, e o systemd pode injetar o mesmo ficheiro com EnvironmentFile= (secção seguinte); combinar ambos é inofensivo, porque nenhuma das bibliotecas substitui uma variável já existente. Se o token for exposto, redefina-o imediatamente no Developer Portal em Bot → Reset Token.
Um bot mínimo em discord.py e discord.js
Ambos os exemplos leem o token a partir do ambiente, ativam a intent Message Content e respondem a !ping. No Developer Portal, crie uma aplicação, adicione um utilizador bot, copie o token (mostrado uma única vez), ative Message Content Intent em Bot → Privileged Gateway Intents e convide o bot para um servidor de teste através do gerador de URL OAuth2 com o âmbito 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);
Execute-o uma vez em primeiro plano: sudo -u bot /opt/mybot/.venv/bin/python /opt/mybot/bot.py ou sudo -u bot node /opt/mybot/index.js, aguarde por Logged in as, envie !ping e faça Ctrl-C. Neste momento o bot vive apenas enquanto durar a sua sessão SSH: fechar o terminal envia SIGHUP aos processos filhos e o bot morre.
Executá-lo sob systemd com Restart=always
O systemd já é o sistema de init do Ubuntu, por isso a forma mais limpa de manter o bot online após o logout, uma falha ou um reinício é uma unidade de serviço: sem daemon adicional e com os logs a chegarem ao journal.
Passo 1: escrever a unidade
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
Para discord.js, defina ExecStart=/usr/bin/node /opt/mybot/index.js e remova a linha PYTHONUNBUFFERED. As diretivas que importam:
Restart=alwaysreinicia o processo em qualquer saída, tanto numa falha como numsys.exit()limpo;RestartSec=5evita que um bot que morre de imediato (token errado, erro de sintaxe) entre num ciclo apertado.Wants=/After=network-online.targetadiam o arranque até a rede estar disponível, para que o primeiro login após um reinício não falhe no DNS.PYTHONUNBUFFERED=1: sem terminal, o Python usa buffer por blocos nostdoute as linhas deprint()chegam ao journal com minutos de atraso ou só à saída.- As linhas
Protect*,PrivateTmpeNoNewPrivilegestornam o resto do sistema de ficheiros só de leitura ou invisível para o bot; acrescente emReadWritePaths=qualquer diretório onde ele tenha de escrever.
Passo 2: ativar, iniciar e verificar
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
O enable cria o symlink de arranque e o --now inicia a unidade. A linha kill é o verdadeiro teste: se systemctl status mybot mostrar active (running) alguns segundos depois, a política de reinício funciona, e um sudo reboot comprova o arranque no boot. Para o ver ao lado de todos os outros serviços, liste os serviços em execução com systemctl; aparece como mybot.service, e systemctl is-enabled mybot confirma que voltará após um reinício.
Alternativa: pm2 e como se compara a screen, nohup e Docker
Qualquer forma de manter um bot vivo responde a três perguntas: sobrevive ao fecho da sessão SSH, reinicia após uma falha e arranca no boot?
| Método | Sobrevive ao logout SSH | Reinicia após falha | Arranca no boot | Veredito |
|---|---|---|---|---|
nohup / & | Yes | No | No | Apenas para testes rápidos. |
screen / tmux | Yes | No | Não, salvo se houver script | Depuração, não produção. |
| pm2 | Yes | Yes | Sim, após pm2 startup + pm2 save | Bom para equipas Node.js; uma só CLI para logs e reinícios. |
| unidade systemd | Yes | Sim (Restart=) | Sim (enable) | Recomendado; sem software adicional e com hardening incluído. |
Docker, restart: unless-stopped | Yes | Yes | Sim, com o daemon do Docker | Bom quando o bot já é distribuído como imagem. |
O pm2 é a escolha popular no mundo Node.js e também lida com Python. Execute-o com a conta proprietária do 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
O pm2 startup gera uma unidade systemd pm2-<user> que ressuscita no boot a lista de processos guardada, ou seja, o pm2 assenta sobre o systemd em vez de o substituir: é o argumento honesto para usar o systemd diretamente com um único bot. O pm2 justifica-se com vários processos Node ou com uma equipa que já o conhece.
Se preferir contentores, o equivalente é restart: unless-stopped num ficheiro Compose; o guia para instalar o Docker num VPS Ubuntu cobre o motor, o Compose e o comportamento no arranque. A ressalva sobre o ufw não afeta um bot, que não publica portas.
Logs, atualizações e dimensionamento da memória
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
O journald faz a rotação e a compressão sozinho. Se o bot escrever o seu próprio ficheiro de log, use logging.handlers.RotatingFileHandler em Python ou um transporte com rotação com pino ou winston em Node, para que um handler falador não encha o disco.
Atualizações
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
Um reinício corta a ligação ao gateway durante alguns segundos; a biblioteca reconecta-se e os utilizadores raramente reparam. Fixe as versões das bibliotecas em requirements.txt ou package-lock.json e leia o changelog antes de uma subida de versão maior. Mantenha o sistema atualizado com sudo apt update && sudo apt upgrade ou unattended-upgrades.
De quanta RAM precisa o bot?
Não dimensione com números genéricos; meça. O systemctl status mybot imprime uma linha Memory: e o pm2 list mostra o mesmo. Um bot discord.py só com comandos costuma ficar em repouso nas dezenas de megabytes; um bot discord.js acrescenta o runtime do Node. A memória cresce com o estado: caches de membros e mensagens em servidores grandes, voz e música (um processo ffmpeg por stream), geração de imagens ou uma base de dados. Na prática, 1 GB de RAM executa confortavelmente o sistema mais um bot pequeno ou médio; bots com muita voz ou vários bots na mesma máquina justificam 2 GB ou mais, e acima de 2500 servidores o Discord exige sharding, o que multiplica o consumo. Duas redes de segurança baratas: MemoryMax=512M na unidade, para que uma fuga reinicie o bot em vez de derrubar a máquina, e um pequeno ficheiro de swap.
Tudo isto pressupõe uma máquina Linux com acesso root que se mantém ligada 24 horas por dia. Se ainda lhe falta essa máquina, o VPS para bots do Discord da rdp.monster fica online cerca de 10 segundos após a confirmação do pagamento, com CPU e RAM dedicados, acesso root total, largura de banda ilimitada (fair-use), sem KYC, com criptomoedas aceites, a partir de $8.99/mês, para que o passo systemctl enable --now mybot acima possa ser a última coisa que escreve antes de o bot ficar verde.
Perguntas frequentes
Posso hospedar um bot do Discord gratuitamente 24/7?
systemd reinicia o bot após falhas e reinícios e ninguém o suspende por estar parado.Um bot do Discord precisa de IP fixo ou de portas abertas no VPS?
Posso executar vários bots do Discord num só VPS?
/opt/bot-a e /opt/bot-b, o seu .env com o seu token e o seu ficheiro de unidade, e depois faça systemctl enable --now a cada um. Utilizadores de sistema separados impedem que um bug num bot leia o token do outro. O único orçamento partilhado é a RAM e o CPU: acompanhe o systemctl status de cada unidade e mude para um plano maior quando o total se aproximar do limite.Devo hospedar um bot do Discord num VPS Windows ou Linux?
systemd de dez linhas. Em Windows usaria o Task Scheduler ou o NSSM para obter o mesmo arranque automático, com mais cliques.Adrien Roche, Editor de infraestrutura e hospedagem
Engenheiro de sistemas com mais de 10 anos cuidando de parques de servidores Windows Server e Linux. Adrien mantém a documentação de infraestrutura do rdp.monster e escreve nossos guias sobre RDP, hospedagem VPS, administração de servidores, redes e ferramentas de privacidade.




