Strona główna » Blog » Hosting bota Discord na VPS: online 24/7
Hosting bota Discord na VPS: online 24/7
- 18 października 2026
- 09:00
- Autor: Adrien Roche
- Tutoriale

Dlaczego to właśnie na VPS boty Discord naprawdę zostają online
Bot Discord to nie strona internetowa. Po zalogowaniu utrzymuje trwałe połączenie WebSocket z bramą Discorda i musi nieprzerwanie odpowiadać na pakiety heartbeat; gdy proces się zatrzyma, bot pokazuje się jako offline, a każda komenda przestaje działać. Ten jeden wymóg, czyli proces, który nigdy nie zasypia, eliminuje większość „darmowych” hostingów:
- Heroku usunął darmowe dyno w listopadzie 2022 roku.
- Replit nie utrzymuje już darmowych projektów w ruchu; tryb always-on przeniesiono do płatnych wdrożeń.
- Glitch zakończył hosting aplikacji w 2025 roku.
- Darmowe plany webowe, które usypiają po okresie bezczynności, przerywają połączenie z bramą przy każdym przestoju; dla użytkowników taki bot jest po prostu niedostępny.
Hosting bota Discord na VPS rozwiązuje to u źródła: maszyna z Linuksem i dostępem root, działająca całą dobę, gdzie bot jest po prostu kolejną usługą zarządzaną przez system init. W tym przewodniku budujemy to na Ubuntu 24.04 (działa też na 22.04 i Debianie 12) z discord.py oraz discord.js, a następnie omawiamy obsługę tokena, restarty, logi, aktualizacje i pamięć.
Przygotowanie VPS: dedykowany użytkownik i środowisko uruchomieniowe
Najpierw zabezpiecz drzwi wejściowe: włącz SSH w Ubuntu i utwardź je uwierzytelnianiem kluczem, blokadą logowania na root i ufw. Bot łączy się z Discordem na zewnątrz i nie potrzebuje żadnych portów przychodzących, więc firewall może pozostać zamknięty dla wszystkiego poza SSH.
Krok 1: utwórz nieuprzywilejowane konto dla bota
sudo useradd -r -m -d /opt/mybot -s /usr/sbin/nologin bot
Dedykowane konto sprawia, że wadliwy bot albo skompromitowana zależność z npm lub PyPI nie odczyta twoich kluczy SSH ani nie tknie innych usług. Wszystko znajduje się w /opt/mybot, którego właścicielem jest bot.
Krok 2 (Python): zainstaluj discord.py w wirtualnym środowisku
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 wymaga Pythona 3.8 lub nowszego; Ubuntu 24.04 dostarcza 3.12, a 22.04 wersję 3.10, więc interpreter z dystrybucji w zupełności wystarczy. Dodaj discord.py[voice] oraz ffmpeg tylko wtedy, gdy potrzebujesz kanałów głosowych.
Krok 3 (Node.js): zainstaluj aktualną wersję LTS i 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'
Pakiet nodejs z repozytoriów Ubuntu jest wyraźnie opóźniony wobec wydań upstream, a discord.js v14 potrzebuje nowoczesnego środowiska, więc użyj NodeSource (powyżej) albo nvm, aby uzyskać aktualne LTS. Przy nvm uruchom which node i użyj tej bezwzględnej ścieżki w pliku jednostki usługi.
Trzymaj token poza kodem: plik .env
Token bota to hasło dające pełną kontrolę nad botem: nigdy nie wklejaj go do bot.py ani index.js i nigdy nie commituj. Umieść go w /opt/mybot/.env, dostępnym do odczytu wyłącznie dla konta bota, korzystając z edytora zamiast echo, ponieważ token wpisany w wierszu poleceń trafia do historii powłoki:
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
Format to jedno KEY=value na linię, bez cudzysłowów i bez export. Odczytują go python-dotenv oraz pakiet npm dotenv, a systemd potrafi wstrzyknąć ten sam plik przez EnvironmentFile= (następna sekcja); łączenie obu podejść jest nieszkodliwe, bo żadna z bibliotek nie nadpisuje istniejącej już zmiennej. Jeśli token kiedykolwiek wycieknie, natychmiast zresetuj go w Developer Portal w sekcji Bot → Reset Token.
Minimalny bot w discord.py i discord.js
Oba przykłady odczytują token ze środowiska, włączają intencję Message Content i odpowiadają na !ping. W Developer Portal utwórz aplikację, dodaj użytkownika bota, skopiuj token (pokazywany tylko raz), włącz Message Content Intent w Bot → Privileged Gateway Intents i zaproś bota na serwer testowy przez generator adresów OAuth2 z zakresem 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);
Uruchom go raz na pierwszym planie: sudo -u bot /opt/mybot/.venv/bin/python /opt/mybot/bot.py lub sudo -u bot node /opt/mybot/index.js, poczekaj na Logged in as, wyślij !ping, a potem naciśnij Ctrl-C. Na tym etapie bot żyje tylko tak długo, jak twoja sesja SSH: zamknięcie terminala wysyła SIGHUP do procesów potomnych i bot ginie.
Uruchom go pod systemd z Restart=always
systemd jest już systemem init w Ubuntu, więc najczystszym sposobem na utrzymanie bota online po wylogowaniu, awarii i restarcie jest jednostka usługi: żadnego dodatkowego demona, a logi trafiają do dziennika.
Krok 1: napisz jednostkę
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
Dla discord.js ustaw ExecStart=/usr/bin/node /opt/mybot/index.js i usuń linię PYTHONUNBUFFERED. Dyrektywy, które mają znaczenie:
Restart=alwaysrestartuje proces po każdym zakończeniu, zarówno po awarii, jak i po czystymsys.exit();RestartSec=5chroni bota, który ginie natychmiast (zły token, błąd składni), przed kręceniem się w ciasnej pętli.Wants=/After=network-online.targetopóźniają start do momentu podniesienia sieci, żeby pierwsze logowanie po restarcie nie poległo na DNS.PYTHONUNBUFFERED=1: bez terminala Python buforujestdoutblokowo, a linieprint()trafiają do dziennika z kilkuminutowym opóźnieniem albo dopiero przy zakończeniu.- Linie
Protect*,PrivateTmpiNoNewPrivilegessprawiają, że reszta systemu plików jest dla bota tylko do odczytu lub niewidoczna; każdy katalog, do którego musi pisać, dodaj doReadWritePaths=.
Krok 2: włącz, uruchom i zweryfikuj
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 tworzy dowiązanie startowe, a --now uruchamia jednostkę. Linia kill to prawdziwy test: jeśli kilka sekund później systemctl status mybot pokazuje active (running), polityka restartu działa, a sudo reboot potwierdza ścieżkę startu przy uruchomieniu systemu. Aby zobaczyć go obok wszystkich innych usług, wypisz działające usługi za pomocą systemctl; pojawia się jako mybot.service, a systemctl is-enabled mybot potwierdza, że wróci po restarcie.
Alternatywa: pm2 i porównanie ze screen, nohup oraz Dockerem
Każdy sposób utrzymywania bota przy życiu odpowiada na trzy pytania: czy przetrwa wylogowanie z SSH, czy restartuje się po awarii i czy startuje po ponownym uruchomieniu maszyny?
| Metoda | Przetrwa wylogowanie z SSH | Restart po awarii | Start po restarcie systemu | Werdykt |
|---|---|---|---|---|
nohup / & | Tak | Nie | Nie | Tylko do szybkich testów. |
screen / tmux | Tak | Nie | Nie, chyba że przez skrypt | Do debugowania, nie na produkcję. |
| pm2 | Tak | Tak | Tak, po pm2 startup + pm2 save | Dobre dla zespołów Node.js; jedno CLI do logów i restartów. |
| jednostka systemd | Tak | Tak (Restart=) | Tak (enable) | Zalecane; bez dodatkowego oprogramowania, z wbudowanym utwardzaniem. |
Docker, restart: unless-stopped | Tak | Tak | Tak, wraz z demonem Dockera | Dobre, gdy bot i tak jest dostarczany jako obraz. |
pm2 to popularny wybór w świecie Node.js i radzi sobie także z Pythonem. Uruchamiaj go na koncie będącym właścicielem bota:
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 generuje jednostkę systemd pm2-<user>, która przy starcie systemu przywraca zapisaną listę procesów, więc pm2 działa na bazie systemd, a nie zamiast niego: to uczciwy argument za używaniem samego systemd dla pojedynczego bota. pm2 zarabia na siebie przy kilku procesach Node albo w zespole, który już go zna.
Jeśli wolisz kontenery, odpowiednikiem jest restart: unless-stopped w pliku Compose; przewodnik, jak zainstalować Dockera na VPS z Ubuntu, omawia silnik, Compose i zachowanie przy starcie systemu. Zastrzeżenie dotyczące ufw nie dotyczy bota, który nie publikuje żadnych portów.
Logi, aktualizacje i dobór pamięci
Logi
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 sam rotuje i kompresuje logi. Jeśli bot zapisuje własny plik dziennika, użyj logging.handlers.RotatingFileHandler w Pythonie albo transportu z rotacją w pino lub winston w Node, żeby gadatliwy handler nie zapełnił dysku.
Aktualizacje
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
Restart przerywa połączenie z bramą na kilka sekund; biblioteka łączy się ponownie i użytkownicy rzadko to zauważają. Przypnij wersje bibliotek w requirements.txt lub package-lock.json i przeczytaj changelog przed większą aktualizacją. Utrzymuj system w aktualności przez sudo apt update && sudo apt upgrade albo unattended-upgrades.
Ile RAM potrzebuje bot?
Nie dobieraj na podstawie ogólnych liczb; zmierz. systemctl status mybot wypisuje linię Memory:, a pm2 list pokazuje to samo. Bot discord.py obsługujący wyłącznie komendy zwykle zajmuje w spoczynku kilkadziesiąt megabajtów; bot discord.js dokłada do tego środowisko Node. Zużycie pamięci rośnie wraz ze stanem: pamięci podręczne członków i wiadomości na dużych serwerach, kanały głosowe i muzyka (proces ffmpeg na każdy strumień), generowanie obrazów czy baza danych. W praktyce 1 GB RAM spokojnie obsłuży system oraz małego lub średniego bota; boty mocno korzystające z kanałów głosowych albo kilka botów na jednej maszynie uzasadniają 2 GB lub więcej, a powyżej 2500 serwerów Discord wymaga shardingu, co zwielokrotnia zużycie. Dwa tanie zabezpieczenia: MemoryMax=512M w jednostce, żeby wyciek restartował bota zamiast kłaść całą maszynę, oraz mały plik wymiany.
Wszystko to zakłada maszynę z Linuksem i dostępem root, która działa całą dobę. Jeśli wciąż takiej szukasz, VPS pod bota Discord od rdp.monster jest online około 10 sekund po potwierdzeniu płatności, z dedykowanym CPU i RAM, pełnym dostępem root, nielimitowanym transferem (fair-use), bez KYC, z płatnościami kryptowalutami, od $8.99/miesiąc, więc powyższy krok systemctl enable --now mybot może być ostatnią rzeczą, jaką wpiszesz, zanim bot zaświeci się na zielono.
Najczęściej zadawane pytania
Czy mogę hostować bota Discord za darmo 24/7?
systemd restartuje bota po awarii i po ponownym uruchomieniu systemu, a nikt nie zawiesza go za bezczynność.Czy bot Discord potrzebuje stałego IP lub otwartych portów na VPS?
Czy mogę uruchomić kilka botów Discord na jednym VPS?
/opt/bot-a i /opt/bot-b, własny plik .env z własnym tokenem oraz własny plik jednostki, a następnie wykonaj systemctl enable --now dla każdego z nich. Oddzielni użytkownicy systemowi sprawiają, że błąd w jednym bocie nie pozwala odczytać tokena drugiego. Jedynym wspólnym budżetem są RAM i CPU: obserwuj systemctl status dla każdej jednostki i przejdź na większy plan, gdy suma zbliża się do limitu.Hostować bota Discord na VPS z Windowsem czy z Linuksem?
systemd. Na Windowsie użyłbyś Harmonogramu zadań lub NSSM, żeby uzyskać to samo zachowanie po restarcie, tylko większym nakładem klikania.Adrien Roche, Redaktor ds. infrastruktury i hostingu
Inżynier systemowy z ponad 10-letnim doświadczeniem w administrowaniu serwerami Windows i Linux. Adrien prowadzi dokumentację infrastruktury rdp.monster i pisze nasze poradniki o RDP, hostingu VPS, administracji serwerami, sieciach i narzędziach prywatności.




