Discord Botを24時間動かす。PythonのBotをVPSで常時起動する

コードが表示されたノートパソコンでキーボードを操作する手元の実写写真を背景に、「Botを24時間/VPSで常時起動」と記した記事見出し。
  • PCを閉じるとBotがオフラインになり、寝ている間はコマンドが使えない
  • VPSを借りたものの、どこに何を置けばBotが動き続けるのかわからない
  • トークンをコードに直接書いていて、漏れたらどうなるのか気になる

PCで動くBotも、PCがスリープした時点でDiscordとの接続が切れ、オフラインになります。

つけっぱなしにしても、更新で再起動するたびに手で起動し直すのは続かないですよね。

24時間動かすときに大事なのは、VPSを借りることより、Botを止まらない仕組みに載せることです。

この記事では、Ubuntuのsystemdに起動を任せ、落ちてもVPSを再起動しても自動で戻る設定を作ります。

VPSのスペックの目安とトークンの発行から始め、コマンドは上から順に貼れば進む形にしました。

トークンはコードの外に置き、止まったときはログの1行から直す場所を決めます。

設定が終われば、PCを閉じて寝ている間も、メンバーがいつでもBotを呼び出せます。

目次
  1. 24時間動かすならPCよりVPS
  2. PCで動かすと止まる場面
  3. VPSならポートを開けずに動く
  4. PCをつけっぱなしにするより確実な理由
  5. 始める前にVPSとトークンを用意する
  6. VPSはメモリー1GBのUbuntuで始める
  7. VPSは手順を進められる条件で選ぶ
  8. Developer Portalでトークンを発行する
  9. VPSでBotを常時起動する手順
  10. 手順1:専用ユーザーと仮想環境を作る
  11. 手順2:Botのコードを置く
  12. 手順3:トークンを別のファイルに置く
  13. 手順4:サービスの設定を書く
  14. 再起動の回数に上限を付ける理由
  15. 手順5:起動して自動起動を有効にする
  16. 動かしたあとの更新と確認
  17. コードを直したら再起動する
  18. discord.pyとUbuntuを更新する
  19. VPSを再起動して自動起動を確かめる
  20. Botがオフラインのときの切り分け
  21. トークンが違うと言われるとき
  22. 特権インテントが必要と言われるとき
  23. discordが見つからないと言われるとき
  24. 再起動が止まったとき
  25. よくある質問
  26. まとめ:systemdへ起動を任せ、VPSの再起動後まで確認する

24時間動かすならPCよりVPS

動かす場所で止まる場面が変わるの比較図。自分のPC:スリープや電源オフで止まる、再起動後は手で起動し直す。VPS:電源を入れたまま動き続ける、再起動後はsystemdが起動する。動かす場所で止まる場面が変わるの比較図。自分のPC:スリープや電源オフで止まる、再起動後は手で起動し直す。VPS:電源を入れたまま動き続ける、再起動後はsystemdが起動する。

discord.pyのBotは、Bot側からDiscordのGatewayへWebSocketでつなぎ、その接続を保っている間だけオンラインになります。

動かす場所の違いは、その接続を保てる時間の違いです。

PCとVPSの違いは次の3つです。

  • PCで動かすと止まる場面
  • VPSならポートを開けずに動く
  • PCをつけっぱなしにするより確実な理由

PCで動かすと止まる場面

PCがスリープするか電源が切れると、Botのプロセスも止まり、接続が切れます。

ターミナルから起動したBotは、そのウィンドウを閉じただけでも終了します。

OSの更新で再起動したあとは、自分で起動し直すまでBotはオフラインのままです。

VPSならポートを開けずに動く

VPSは、データセンターで電源を入れたまま動き続ける仮想のサーバーです。

Gatewayへの接続はBotから外へ向けて張るので、Botのためにポートを開けたり、公開URLを用意したりする必要はありません。

VPSの外から入れる口は、自分が操作するためのSSHだけで足ります。

PCをつけっぱなしにするより確実な理由

PCをつけっぱなしにしても、OSの更新や停電、家族がうっかり電源を切っただけでBotは止まり、気づくのは誰かがコマンドを打って反応がなかったときです。

VPSに載せてsystemdに起動を任せれば、Botが落ちても、VPSが再起動しても、自分が寝ている間に自動で戻ります。

自分のPCは電源を切って構わなくなり、Botのために部屋のPCを動かし続ける電気代や騒音も気にしなくて済みます。

Ubuntu 24.04を選べば、このあとの手順1からそのまま進められます

XServer VPS for Gameを見る

始める前にVPSとトークンを用意する

用意するのは、Ubuntuを入れたVPSと、Developer Portalで発行するBotのトークンです。

VPSにはSSHでログインし、sudoでコマンドを実行できる状態にしておきます。

用意するものと選び方は次の3つです。

  • VPSはメモリー1GBのUbuntuで始める
  • VPSは手順を進められる条件で選ぶ
  • Developer Portalでトークンを発行する

VPSはメモリー1GBのUbuntuで始める

OSは、長く更新が提供されるUbuntu 24.04 LTSを選びます。

VPSで使うUbuntu 24.04のクラウドイメージは、メモリー1GB、ストレージ4GBが最低ラインです。

自分のサーバーで使う小さなBotなら、この最低ラインのプランから始め、動かしたあとの使用量を見て増やすかを決めます。

使用量は、手順5で使うsystemctl statusのMemory:の行に出ます。

VPSは手順を進められる条件で選ぶ

契約先を選ぶ条件は、Ubuntu 24.04を選べること、SSHでログインしてsudoかrootでコマンドを打てること、メモリーが1GB以上あることの3つです。

この3つがそろっていれば、どの事業者のVPSでも、このあとの手順は変わりません。

迷ったときの候補はXServer VPS for Game。

2026年2月からOSだけが入ったUbuntu 24.04のテンプレートを選べるようになり、root権限のあるVPSなので、手順1から記事どおりに進められます。

最小のプランでもメモリー2GB、CPU3コア、NVMe SSD 50GBがあり、小さなBotなら余裕が残るはずです。

その余裕は、FAQで扱う2つ目のBotを同じVPSで動かすときに生きてきます。

ゲーム向けのVPSなので、将来マイクラなどのゲームサーバーを立てたくなっても、契約先を変えずに済むでしょう。

料金は契約期間分の一括前払いです。

最初は1ヶ月の契約にして、Botが動き続けるのを確かめてから期間を延ばしてください。

1ヶ月から契約でき、Botが1週間止まらずに動くかを確かめてから延ばせます

XServer VPS for Gameの料金を見る

Developer Portalでトークンを発行する

Developer PortalでBotのアプリを開き、左のメニューから「Bot」を選びます。

「Token」の欄にある「Reset Token」を押すと、新しいトークンが表示されます。

表示は一度きりなので、パスワード管理アプリなど自分だけが見られる場所に控えてください。

トークンはBotのパスワードと同じで、知った人は誰でもそのBotとしてログインし、Botに与えた権限の範囲で好きな操作ができます。

Botをまだサーバーに入れていなければ、Botを追加する流れでテスト用のサーバーへ追加しておきます。

VPSでBotを常時起動する手順

Botを常時起動にする流れの図。1.専用ユーザーと仮想環境を作る(discord.pyを入れる)、2.Botのコードを置く(トークンは書かない)、3.トークンを別のファイルに置く(rootだけが読める)、4.サービスを登録して起動する(落ちたら30秒後に再起動)の順に進む。Botを常時起動にする流れの図。1.専用ユーザーと仮想環境を作る(discord.pyを入れる)、2.Botのコードを置く(トークンは書かない)、3.トークンを別のファイルに置く(rootだけが読める)、4.サービスを登録して起動する(落ちたら30秒後に再起動)の順に進む。

Botのファイルは/opt/discord-botに、トークンは/etc/discord-botに分けて置きます。

コマンドは、すべてVPSにSSHでログインした画面で入力してください。

次の5つの手順で進め、途中で再起動の回数に上限を付ける理由も説明します。

  • 手順1:専用ユーザーと仮想環境を作る
  • 手順2:Botのコードを置く
  • 手順3:トークンを別のファイルに置く
  • 手順4:サービスの設定を書く
  • 再起動の回数に上限を付ける理由
  • 手順5:起動して自動起動を有効にする

手順1:専用ユーザーと仮想環境を作る

Ubuntu 24.04のPythonには、システム全体へpipでライブラリを入れられない保護がかかっています。

そこでBot専用の仮想環境を作り、その中にdiscord.pyを入れます。

sudo apt update
sudo apt install -y python3-venv
sudo useradd --system --no-create-home --shell /usr/sbin/nologin discordbot
sudo mkdir -p /opt/discord-bot
sudo python3 -m venv /opt/discord-bot/.venv
sudo /opt/discord-bot/.venv/bin/pip install -U discord.py

最後のコマンドでSuccessfully installedの行が出れば、discord.pyが入っています。

discordbotは、Botを動かすためだけの、ログインできないユーザーです。

Botはこのユーザーの権限で動くので、コードに不具合があっても、root権限が要るファイルは書き換えられません。

手順2:Botのコードを置く

動作を確かめるために、ログインしたらログに名前を出すだけのBotを置きます。

すでに作ったBotがある場合も、トークンを読み込む部分はこの形に合わせてください。

sudo nano /opt/discord-bot/bot.py

開いた画面に次のコードを貼り付け、Ctrl+OとEnterで保存し、Ctrl+Xで閉じます。

/opt/discord-bot/bot.py
import logging
import os
from pathlib import Path

import discord

log = logging.getLogger("bot")


def read_token():
    folder = os.environ.get("CREDENTIALS_DIRECTORY")
    if not folder:
        raise SystemExit("トークンが読み込めません。systemdから起動してください")
    return (Path(folder) / "discord-token").read_text(encoding="utf-8").strip()


client = discord.Client(intents=discord.Intents.default())


@client.event
async def on_ready():
    log.info("ログインしました: %s", client.user)


client.run(read_token(), root_logger=True)

read_tokenは、systemdが渡すフォルダからトークンを読む部分です。

このコードはトークンを外部ファイルから読み込み、トークンをコードに直接書かないので、誤って公開する事故を減らせます。

トークンを保存したファイルや、トークンが含まれるログ・バックアップはGitHubなどへ公開しないでください。

root_logger=Trueを付けると、log.infoで書いた行もdiscord.pyのログと同じ場所に出ます。

手順3:トークンを別のファイルに置く

トークンは、root以外が開けないフォルダに、トークンだけを書いたファイルとして保存します。

sudo install -d -m 700 /etc/discord-bot
sudo nano /etc/discord-bot/token
sudo chmod 600 /etc/discord-bot/token

nanoの画面には、Developer Portalで控えたトークンだけを貼り付けて保存します。

systemdはこのファイルをroot権限で読み、起動したBotにだけ読み取り専用の写しを渡します。

サービスの設定のEnvironment=にトークンを書くと、systemdを通じてVPSのほかのユーザーからも読めてしまいます。

そのため、この記事では資格情報を渡すLoadCredential=を使います。

手順4:サービスの設定を書く

systemdは、Ubuntuでサービスの起動と停止を受け持つ仕組みです。

Botをサービスとして登録すると、落ちたときもVPSを再起動したときも、systemdがBotを起動し直します。

sudo nano /etc/systemd/system/discord-bot.service

開いた画面に次の内容を貼り付けて保存します。

/etc/systemd/system/discord-bot.service
[Unit]
Description=Discord bot
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=600
StartLimitBurst=5

[Service]
User=discordbot
WorkingDirectory=/opt/discord-bot
ExecStart=/opt/discord-bot/.venv/bin/python /opt/discord-bot/bot.py
LoadCredential=discord-token:/etc/discord-bot/token
Environment=PYTHONUNBUFFERED=1
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target

User=の行で、手順1で作ったdiscordbotとしてBotを動かします。

LoadCredential=は、手順3のトークンをdiscord-tokenという名前でBotに渡す行です。

Restart=on-failureとRestartSec=30があるので、Botがエラーで終了しても30秒後に起動し直します。

WantedBy=multi-user.targetは、VPSが起動したときにBotも起動させるための行です。

再起動の回数に上限を付ける理由

StartLimitIntervalSec=600とStartLimitBurst=5は、10分間に5回起動したら、それ以上は起動し直さない設定です。

DiscordはGatewayへのログインを24時間で1000回までに制限していて、超えるとBotのトークンがリセットされます。

ログインした直後に落ちる不具合を残したまま再起動を続けると、この回数を使い切ってしまいます。

手順5:起動して自動起動を有効にする

設定ファイルを読み込ませてから、Botを起動します。

sudo systemctl daemon-reload
sudo systemctl enable --now discord-bot
sudo systemctl status discord-bot

enable --nowは、いますぐ起動することと、VPSの起動時にも起動することを一度に設定するオプションです。

Active:がactive (running)になり、下のログにログインしましたの行があれば成功です。

Discordのメンバー一覧でも、Botがオンラインの表示に変わります。

表示はqで閉じられます。

動かしたあとの更新と確認

Botを直したときやVPSを更新したときも、Botの起動はsystemdに任せます。

ターミナルからpythonで直接起動すると、トークンが渡らずにトークンが読み込めませんと出て止まります。

動かしたあとの作業は次の3つです。

  • コードを直したら再起動する
  • discord.pyとUbuntuを更新する
  • VPSを再起動して自動起動を確かめる

コードを直したら再起動する

bot.pyを書き換えて保存したら、サービスを再起動して新しいコードを読み込ませます。

sudo systemctl restart discord-bot

動きを追うときは、Botのログを流しながら表示します。

sudo journalctl -u discord-bot -f

-fを付けると新しい行が出るたびに表示が増え、Ctrl+Cで抜けられます。

discord.pyとUbuntuを更新する

discord.pyは、仮想環境の中のpipで入れ直してから、Botを再起動します。

sudo /opt/discord-bot/.venv/bin/pip install -U discord.py
sudo systemctl restart discord-bot

Ubuntu本体は、aptでまとめて更新します。

sudo apt update
sudo apt upgrade -y

/var/run/reboot-requiredというファイルができていたら、VPSを再起動するまで更新の一部が反映されません。

手順5で自動起動を有効にしてあるので、VPSを再起動してもBotは自分で戻ります。

VPSを再起動して自動起動を確かめる

自動起動の設定は、一度VPSを再起動して確かめておきます。

sudo reboot

再起動が終わったらSSHでログインし直し、sudo systemctl status discord-botでactive (running)に戻っているかを見ます。

Discordでもオンラインに戻っていれば、更新や障害でVPSが再起動したあとも、人の手を借りずにBotが動き続けます。

Botがオフラインのときの切り分け

ログの行で直す場所を決めるの図。「ログに出ている行は?」から分かれる。Improper tokenならトークンを貼り直す(Reset Tokenで再発行)。privileged intentsならインテントをオンにする(Developer Portalの「Bot」)。No module named 'discord'なら仮想環境に入れ直す。start-limit-hitなら原因を直してreset-failed。ログの行で直す場所を決めるの図。「ログに出ている行は?」から分かれる。Improper tokenならトークンを貼り直す(Reset Tokenで再発行)。privileged intentsならインテントをオンにする(Developer Portalの「Bot」)。No module named 'discord'なら仮想環境に入れ直す。start-limit-hitなら原因を直してreset-failed。

Botがオフラインのままなら、まずログの最後の30行を表示します。

sudo journalctl -u discord-bot -n 30 --no-pager

最後のほうに出ている英語の行で、直す場所が決まります。

ログに出るメッセージごとに、次の4つの場合に分けて説明します。

  • トークンが違うと言われるとき
  • 特権インテントが必要と言われるとき
  • discordが見つからないと言われるとき
  • 再起動が止まったとき

トークンが違うと言われるとき

次の行が出ていれば、保存したトークンが間違っています。

discord.errors.LoginFailure: Improper token has been passed.

トークンの前にTOKEN=や引用符を付けた場合も、この行が出ます。

Developer Portalの「Reset Token」で発行し直し、手順3のファイルをトークンだけに書き換えます。

そのあとsudo systemctl restart discord-botでBotを起動し直してください。

特権インテントが必要と言われるとき

requesting privileged intentsを含む行は、コードで有効にしたインテントが、Developer Portalではオフのままという意味です。

Developer Portalの「Bot」で同じインテントをオンにして保存し、サービスを再起動します。

discordが見つからないと言われるとき

ModuleNotFoundError: No module named 'discord'は、ExecStart=で指定したPythonにdiscord.pyが入っていない状態です。

ExecStart=が/opt/discord-bot/.venv/bin/pythonで始まっているかを見て、手順1のpip installを実行し直します。

再起動が止まったとき

statusにstart-limit-hitと出ていれば、10分間に5回の上限に達し、systemdが起動をやめています。

ログで原因を直したら、失敗の記録を消してから起動してください。

sudo systemctl reset-failed discord-bot
sudo systemctl start discord-bot

よくある質問

VPSは止めずに、Botだけを止めるにはどうしますか。

「sudo systemctl stop discord-bot」を実行すると、Botだけが止まります。

VPSを起動したときにも起動させたくない場合は、「sudo systemctl disable discord-bot」もあわせて実行します。

トークンが漏れたかもしれないときは、どうしますか。

Developer PortalのBotのページで、すぐに「Reset Token」を押します。

古いトークンは使えなくなるので、新しいトークンを「/etc/discord-bot/token」に保存し、サービスを再起動してください。

同じVPSで2つ目のBotも動かせますか。

フォルダ、トークンのファイル、サービスの名前をBotごとに分ければ動かせます。

たとえば「/opt/second-bot」と「second-bot.service」を作り、「LoadCredential=」の行は新しいトークンのファイルに向けます。

まとめ:systemdへ起動を任せ、VPSの再起動後まで確認する

PythonのBotをPCに頼らず動かすには、VPS上のsystemdへ起動と異常終了時の再起動を任せます。

トークンはコードと分け、保存したファイルやログを公開しないことも必要です。

設定後はサービスが動いているだけでなく、Discordへログインできたかを確かめましょう。

一度VPSを再起動し、Botがオンラインへ戻れば、自動起動の設定まで確認できます。

戻らないときは再起動を繰り返さず、journalctlのログから原因を調べます。

起動回数の上限で止まっている場合も、原因を直してからサービスを起動し直してください。