RDP Monster

Host bot Discord trên VPS: giữ bot online 24/7

Host bot Discord trên VPS: giữ bot online 24/7

Vì sao VPS là nơi bot Discord thực sự luôn online

Bot Discord không phải là một trang web. Sau khi đăng nhập, nó duy trì một kết nối WebSocket liên tục tới gateway của Discord và phải trả lời heartbeat không ngừng; khi tiến trình dừng, bot hiển thị offline và mọi lệnh đều thất bại. Chỉ riêng yêu cầu đó, một tiến trình không bao giờ ngủ, đã loại bỏ phần lớn các dịch vụ host "miễn phí":

  • Heroku đã gỡ bỏ dyno miễn phí vào tháng 11 năm 2022.
  • Replit không còn giữ các dự án miễn phí chạy liên tục; chế độ always-on đã chuyển sang các gói deployment trả phí.
  • Glitch đã chấm dứt dịch vụ host ứng dụng vào năm 2025.
  • Các gói web miễn phí ngủ sau một thời gian không hoạt động sẽ cắt kết nối gateway mỗi lần rảnh; với người dùng, bot đó đơn giản là đã chết.

Host bot Discord trên VPS giải quyết tận gốc vấn đề này: một máy Linux có quyền root chạy suốt ngày đêm, nơi bot chỉ là một dịch vụ nữa do hệ thống init quản lý. Hướng dẫn này dựng hệ thống đó trên Ubuntu 24.04 (cũng áp dụng cho 22.04 và Debian 12) với discord.py và discord.js, sau đó đề cập đến việc xử lý token, khởi động lại, log, cập nhật và bộ nhớ.

Chuẩn bị VPS: một người dùng riêng và một môi trường chạy

Hãy bảo vệ cửa chính trước: bật SSH trên Ubuntu và gia cố bảo mật với xác thực bằng khóa, cấm đăng nhập root và ufw. Bot chỉ kết nối ra ngoài tới Discord và không cần cổng vào nào, nên tường lửa có thể đóng mọi thứ trừ SSH.

Bước 1: tạo một tài khoản không có đặc quyền cho bot

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

Một tài khoản riêng đồng nghĩa với việc một bot lỗi hoặc một thư viện npm hay PyPI bị xâm phạm không thể đọc khóa SSH của bạn hay động vào các dịch vụ khác. Mọi thứ nằm trong /opt/mybot, thuộc sở hữu của bot.

Bước 2 (Python): cài discord.py trong môi trường ảo

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 yêu cầu Python 3.8 trở lên; Ubuntu 24.04 đi kèm 3.12 và 22.04 đi kèm 3.10, nên trình thông dịch của bản phân phối là đủ dùng. Chỉ thêm discord.py[voice] và ffmpeg khi bạn cần kênh thoại.

Bước 3 (Node.js): cài bản LTS hiện hành và 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'

Gói nodejs của chính Ubuntu tụt hậu khá xa so với bản gốc và discord.js v14 cần một runtime hiện đại, vì vậy hãy dùng NodeSource (như trên) hoặc nvm để có bản LTS hiện hành. Với nvm, hãy chạy which node và dùng đường dẫn tuyệt đối đó trong unit dịch vụ.

Giữ token ngoài mã nguồn: file .env

Token của bot là một mật khẩu có toàn quyền điều khiển bot: đừng bao giờ dán nó vào bot.py hay index.js, đừng bao giờ commit nó. Hãy đặt nó trong /opt/mybot/.env, chỉ tài khoản bot đọc được, và dùng trình soạn thảo thay vì echo, vì token gõ trên dòng lệnh sẽ nằm lại trong lịch sử 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

Định dạng là một cặp KEY=value mỗi dòng, không dấu ngoặc kép, không export. python-dotenv và gói npm dotenv đọc được file này, và systemd có thể nạp chính file đó bằng EnvironmentFile= (phần tiếp theo); kết hợp cả hai cũng không sao, vì không thư viện nào ghi đè biến đã tồn tại. Nếu token bị lộ, hãy reset ngay trong Developer Portal tại Bot → Reset Token.

Một bot tối giản bằng discord.py và discord.js

Cả hai ví dụ đều đọc token từ biến môi trường, bật intent Message Content và trả lời !ping. Trong Developer Portal, hãy tạo một application, thêm bot user, sao chép token (chỉ hiển thị một lần), bật Message Content Intent tại Bot → Privileged Gateway Intents, và mời bot vào một server thử nghiệm qua công cụ tạo URL OAuth2 với 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);

Chạy thử ở chế độ foreground một lần: sudo -u bot /opt/mybot/.venv/bin/python /opt/mybot/bot.py hoặc sudo -u bot node /opt/mybot/index.js, chờ dòng Logged in as, gửi !ping, rồi nhấn Ctrl-C. Lúc này bot chỉ sống chừng nào phiên SSH của bạn còn mở: đóng terminal sẽ gửi SIGHUP tới các tiến trình con và bot sẽ chết.

Chạy bot dưới systemd với Restart=always

systemd vốn đã là hệ thống init của Ubuntu, nên cách gọn gàng nhất để giữ bot online sau khi đăng xuất, crash và khởi động lại là một unit dịch vụ: không cần daemon bổ sung, và log được ghi vào journal.

Bước 1: viết 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

Với discord.js, đặt ExecStart=/usr/bin/node /opt/mybot/index.js và bỏ dòng PYTHONUNBUFFERED. Các chỉ thị quan trọng:

  • Restart=always khởi động lại tiến trình mỗi khi nó thoát, dù là crash hay sys.exit() bình thường; RestartSec=5 ngăn một bot chết ngay lập tức (token sai, lỗi cú pháp) quay vòng liên tục không nghỉ.
  • Wants=/After=network-online.target trì hoãn việc khởi động cho đến khi mạng sẵn sàng, để lần đăng nhập đầu tiên sau khi khởi động lại không thất bại vì DNS.
  • PYTHONUNBUFFERED=1: khi không có terminal, Python đệm stdout theo khối, và các dòng print() đến journal trễ vài phút hoặc chỉ khi thoát.
  • Các dòng Protect*, PrivateTmp và NoNewPrivileges khiến phần còn lại của hệ thống tệp chỉ đọc hoặc vô hình với bot; hãy thêm thư mục nào bot cần ghi vào ReadWritePaths=.

Bước 2: bật, khởi động và kiểm tra

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 tạo symlink khởi động cùng hệ thống và --now khởi động unit ngay. Dòng kill mới là bài kiểm tra thực sự: nếu vài giây sau systemctl status mybot hiển thị active (running), chính sách khởi động lại đã hoạt động, và một lệnh sudo reboot sẽ chứng minh đường khởi động. Để xem nó cùng mọi dịch vụ khác, hãy liệt kê các dịch vụ đang chạy bằng systemctl; nó hiện ra với tên mybot.service, và systemctl is-enabled mybot xác nhận nó sẽ quay lại sau khi khởi động lại.

Lựa chọn thay thế: pm2, và so sánh với screen, nohup và Docker

Mọi cách giữ bot sống đều phải trả lời ba câu hỏi: nó có sống sót khi đăng xuất SSH, tự khởi động lại khi crash, và tự chạy khi khởi động lại máy không?

Phương phápSống sót khi đăng xuất SSHKhởi động lại khi crashTự chạy khi khởi động máyKết luận
nohup / &CóKhôngKhôngChỉ để thử nhanh.
screen / tmuxCóKhôngKhông, trừ khi viết scriptĐể gỡ lỗi, không dùng cho production.
pm2CóCóCó, sau pm2 startup + pm2 saveTốt cho đội ngũ Node.js; một CLI duy nhất cho log và khởi động lại.
Unit systemdCóCó (Restart=)Có (enable)Khuyên dùng; không cần phần mềm bổ sung, có sẵn tính năng gia cố bảo mật.
Docker, restart: unless-stoppedCóCóCó, thông qua Docker daemonTốt khi bot đã được đóng gói sẵn thành image.

pm2 là lựa chọn phổ biến trong thế giới Node.js và cũng xử lý được Python. Hãy chạy nó bằng tài khoản sở hữu 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 tạo ra một unit systemd pm2-<user> để khôi phục danh sách tiến trình đã lưu khi khởi động, nghĩa là pm2 nằm trên nền systemd chứ không thay thế nó: đó là lý lẽ thẳng thắn để dùng trực tiếp systemd cho một bot đơn lẻ. pm2 phát huy giá trị khi bạn có nhiều tiến trình Node hoặc một đội ngũ đã quen dùng nó.

Nếu bạn thích container, cách tương đương là restart: unless-stopped trong một file Compose; hướng dẫn cài Docker trên VPS Ubuntu đề cập đến engine, Compose và hành vi khi khởi động. Lưu ý về ufw trong đó không ảnh hưởng đến bot, vì bot không công khai cổng nào.

Log, cập nhật và tính toán bộ nhớ

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 tự xoay vòng và nén log. Nếu bot tự ghi file log riêng, hãy dùng logging.handlers.RotatingFileHandler trong Python hoặc một transport có xoay vòng với pino hay winston trong Node, để một handler ghi log quá nhiều không thể làm đầy ổ đĩa.

Cập nhật

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

Việc khởi động lại sẽ ngắt kết nối gateway trong vài giây; thư viện tự kết nối lại và người dùng hiếm khi nhận ra. Hãy cố định phiên bản thư viện trong requirements.txt hoặc package-lock.json và đọc changelog trước khi nâng phiên bản lớn. Giữ hệ điều hành luôn cập nhật bằng sudo apt update && sudo apt upgrade hoặc unattended-upgrades.

Bot cần bao nhiêu RAM?

Đừng ước lượng theo các con số chung chung; hãy đo. systemctl status mybot in ra dòng Memory: và pm2 list cũng hiển thị như vậy. Một bot discord.py chỉ xử lý lệnh thường dùng vài chục megabyte khi nhàn rỗi; bot discord.js thì mang thêm cả runtime Node. Bộ nhớ tăng theo trạng thái: bộ nhớ đệm thành viên và tin nhắn trên các server lớn, voice và nhạc (mỗi luồng một tiến trình ffmpeg), tạo ảnh hoặc cơ sở dữ liệu. Trên thực tế, 1 GB RAM đủ thoải mái cho hệ điều hành cùng một bot cỡ nhỏ hoặc vừa; bot dùng voice nhiều hoặc nhiều bot trên một máy thì nên có từ 2 GB trở lên, và khi vượt quá 2.500 server, Discord bắt buộc sharding, khiến mức sử dụng tài nguyên tăng lên nhiều lần. Hai lưới an toàn rẻ tiền: MemoryMax=512M trong unit, để rò rỉ bộ nhớ chỉ khiến bot khởi động lại thay vì kéo sập cả máy, và một file swap nhỏ.

Tất cả những điều trên giả định bạn có một máy Linux với quyền root chạy suốt ngày đêm. Nếu bạn vẫn cần chiếc máy đó, VPS bot Discord của rdp.monster sẵn sàng hoạt động khoảng 10 giây sau khi thanh toán được xác nhận, với CPU và RAM chuyên dụng, toàn quyền root, băng thông không giới hạn (sử dụng hợp lý), không cần KYC, chấp nhận tiền mã hóa, chỉ từ $8.99/tháng, nên bước systemctl enable --now mybot ở trên có thể là lệnh cuối cùng bạn gõ trước khi bot sáng đèn xanh.

Câu hỏi thường gặp

Tôi có thể host bot Discord miễn phí 24/7 không?

Không còn đáng tin cậy nữa: các gói miễn phí từng giữ bot luôn thức đã bị gỡ bỏ hoặc giờ sẽ ngủ khi không hoạt động.
Heroku đã bỏ dyno miễn phí vào tháng 11 năm 2022, Replit chuyển chế độ always-on sang các gói deployment trả phí, và Glitch đã chấm dứt dịch vụ host ứng dụng vào năm 2025. Các gói web miễn phí còn lại đều ngủ sau một thời gian không hoạt động, làm đóng kết nối gateway của bot. Chạy bot trên PC của bạn chỉ hoạt động cho đến khi PC khởi động lại hoặc ngủ. Lựa chọn đáng tin cậy rẻ nhất là một VPS nhỏ với khoảng 1 GB RAM, nơi systemd khởi động lại bot khi crash hoặc khởi động lại máy và không ai tạm ngưng nó vì nhàn rỗi.

Bot Discord có cần IP tĩnh hoặc mở cổng trên VPS không?

Không: bot kết nối ra ngoài tới Discord, nên không cần mở cổng vào nào và IP không quan trọng.
Bot gateway mở một kết nối WebSocket ra ngoài tới Discord và nhận sự kiện qua chính kết nối đó, nên tường lửa trên VPS có thể đóng mọi thứ trừ SSH, và IP của máy chủ không bao giờ hiển thị với người dùng. Bạn chỉ cần mở cổng và có tên miền công khai nếu chuyển sang HTTP interaction endpoint, mà Discord gọi qua một URL bạn đăng ký, hoặc nếu bạn thêm một bảng điều khiển web. Khi đó hãy đặt nó sau HTTPS với một reverse proxy.

Tôi có thể chạy nhiều bot Discord trên một VPS không?

Có, mỗi bot một unit systemd (hoặc một tiến trình pm2), lý tưởng nhất là mỗi bot dưới người dùng và thư mục riêng.
Không có gì giới hạn bạn chỉ một bot trên mỗi máy. Hãy cho mỗi bot một thư mục riêng như /opt/bot-a và /opt/bot-b, một file .env riêng với token riêng, và một file unit riêng, rồi chạy systemctl enable --now cho từng bot. Các người dùng hệ thống riêng biệt ngăn lỗi ở một bot đọc được token của bot kia. Tài nguyên dùng chung duy nhất là RAM và CPU: theo dõi systemctl status cho từng unit, và chuyển sang gói lớn hơn khi tổng mức sử dụng gần chạm giới hạn.

Nên host bot Discord trên VPS Windows hay VPS Linux?

Linux là lựa chọn mặc định cho bot: rẻ hơn, nhẹ hơn, và bộ công cụ (systemd, pm2, Docker) được xây dựng cho nó.
Cả discord.py và discord.js đều chạy được trên Windows, và VPS Windows là lựa chọn đúng nếu bot phụ thuộc vào một ứng dụng chỉ có trên Windows hoặc đơn giản là bạn thích có giao diện desktop. Với một bot thông thường, Linux thắng: hệ điều hành chỉ dùng một phần nhỏ RAM, một máy chủ tối giản gần như không có bề mặt tấn công, và giữ một tiến trình luôn chạy chỉ cần một unit systemd mười dòng. Trên Windows, bạn sẽ dùng Task Scheduler hoặc NSSM để có cùng hành vi tự khởi động lại khi boot nhưng phải nhấp chuột nhiều hơn.

Adrien Roche, Biên tập viên hạ tầng & hosting

Kỹ sư hệ thống với hơn 10 năm vận hành các hệ thống Windows Server và Linux. Adrien phụ trách tài liệu hạ tầng của rdp.monster và viết các hướng dẫn về RDP, hosting VPS, quản trị máy chủ, mạng và công cụ bảo vệ quyền riêng tư.

Đăng ký chương trình đại lý của chúng tôi

Thông tin của bạn

Nếu bạn có bất kỳ câu hỏi nào, liên hệ với chúng tôi tại đây !
Họ và tên(Bắt buộc)
Nhập địa chỉ email của bạn, bạn cần có tài khoản trên manager.rdp.monster !

Công ty của bạn

Nhập địa chỉ website của bạn nếu có
Giải thích ngắn gọn cách bạn sẽ bán dịch vụ cho khách hàng. Ví dụ: trò chuyện với mọi người trên các diễn đàn.

Đến quái vật cũng mê cookie!

Chúng tôi sử dụng cookie để cải thiện trải nghiệm duyệt web của bạn, hiển thị quảng cáo hoặc nội dung phù hợp và phân tích lưu lượng truy cập. Khi nhấn "Chấp nhận", bạn đồng ý với việc chúng tôi sử dụng cookie.