PythonでDiscord Botを作ったあと、「自分のパソコンを閉じても動かしておきたい」と思うことはありませんか?
Linuxサーバーで動かせば、手元のパソコンを起動し続ける必要がなくなります。ただ、SSHで接続してPythonを実行するだけでは、接続を切ったときにBotが終了する場合があります。
そこで今回は、Linuxの「systemd」を使い、Botの起動・停止を管理する方法を紹介します。サーバー起動時の自動起動や、異常終了したときの再起動も設定します。
今回の環境と準備するもの
この記事では、次の構成を使用します。
- Ubuntu・Debian系のLinuxサーバー
- Pythonとdiscord.py
- systemdによる起動管理
- sudoを使用できる作業用アカウント
Botは作成済みで、Discordサーバーへの招待も済んでいる前提です。起動するファイル名はmain.pyとします。
サーバーにはVPSや自宅のLinuxパソコンなどを使えます。ただし、サーバー自体の電源やインターネット接続が切れるとBotも利用できなくなります。
まず、SSHなどでサーバーに接続し、必要なパッケージを入れます。
$ sudo apt update
$ sudo apt install python3 python3-venv python3-pip nano
Bot専用のユーザーを作成する
Botを管理者権限で動かす必要はありません。今回は、Botを実行する専用ユーザーdiscordbotを作成します。
$ sudo useradd --system --create-home \
--home-dir /opt/discord-bot \
--shell /usr/sbin/nologin discordbot
続いて、プログラムを置くフォルダを作成します。
$ sudo install -d -o discordbot -g discordbot \
/opt/discord-bot/app
BotのPythonファイルや設定ファイルは、このappフォルダへ配置してください。手元のパソコンから転送する場合は、SFTPなどを使用できます。
配置後、所有者を専用ユーザーに変更します。
$ sudo chown -R discordbot:discordbot /opt/discord-bot/app
この記事では、起動ファイルを次の場所に置きます。
$ /opt/discord-bot/app/main.py
Pythonの仮想環境を作成する
仮想環境は、Botで使うPythonライブラリを分けて管理するためのものです。Linux本体のPython環境に直接インストールせず、Bot専用の環境を作ります。
$ sudo -u discordbot python3 -m venv \
/opt/discord-bot/.venv
discord.pyをインストールします。
$ sudo -u discordbot /opt/discord-bot/.venv/bin/python \
-m pip install discord.py
ほかにも必要なライブラリがある場合は、同じ環境にインストールしてください。requirements.txtがある場合は、次のコマンドでまとめて導入できます。
$ sudo -u discordbot /opt/discord-bot/.venv/bin/python \
-m pip install -r /opt/discord-bot/app/requirements.txt
以降は、仮想環境内のPythonを直接指定して起動します。毎回activateする必要はありません。
Botのトークンを設定する
トークンは、Botにログインするための大切な情報です。コードへ直接書かず、別のファイルに保存して読み込む形にします。
まず、設定ファイルを作成します。
$ sudo -u discordbot nano /opt/discord-bot/app/.env
次の内容を書き、実際のトークンに置き換えて保存します。
DISCORD_TOKEN=ここにBotのトークン
nanoでは、Ctrl+O、Enterで保存し、Ctrl+Xで終了できます。
Python側では、次のように環境変数からトークンを読み込みます。
import os
import discord
intents = discord.Intents.default()
client = discord.Client(intents=intents)
@client.event
async def on_ready():
print(f"ログインしました: {client.user}")
client.run(os.environ["DISCORD_TOKEN"])
これはログイン確認用の最小例です。
既存のBotがある場合は、bot.run()やclient.run()に渡すトークンを変更してください。
メッセージを読む機能などに必要なIntentsは、Botの機能に合わせて設定します。
systemdにBotを登録する
systemdは、Linuxでプログラムの起動や停止を管理する仕組みです。
まず、Bot用の設定ファイルを作成します。
$ sudo nano /etc/systemd/system/discord-bot.service
次の内容を貼り付けて保存してください。
[Unit]
Description=Python Discord Bot
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=discordbot
Group=discordbot
WorkingDirectory=/opt/discord-bot/app
EnvironmentFile=/opt/discord-bot/.env
ExecStart=/opt/discord-bot/.venv/bin/python -u /opt/discord-bot/app/main.py
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
主な設定の意味は次のとおりです。
| 設定 | 内容 |
|---|---|
User | Botを実行するユーザー |
WorkingDirectory | Botが作業するフォルダ |
EnvironmentFile | 環境変数を読み込むファイル |
ExecStart | Botの起動コマンド |
Restart=on-failure | 異常終了したときに再起動 |
RestartSec=10 | 再起動まで10秒待つ |
-uは、Pythonの出力をログへすぐに反映しやすくする指定です。
なお、ネットワークの起動後に実行する設定でも、Discordへ接続できることまでは保証されません。また、この設定では正常終了した場合や、Botが動いたまま処理が止まった場合には自動再起動しません。
Botを起動して動作を確認する
設定をsystemdへ読み込ませ、自動起動を有効にします。
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now discord-bot
enableはサーバー起動時の自動起動、--nowはその場での起動を指定しています。
状態を確認しましょう。
$ sudo systemctl status discord-bot
active (running)と表示されていれば、プログラムは動いています。ただし、Discordへのログイン成功もログで確認してください。
$ sudo journalctl -u discord-bot -n 50 --no-pager
Discord上でもBotの状態やコマンドの動作を確認します。ここまでできれば、SSHの接続を切ってもsystemdがBotを管理してくれます。
ログ確認・停止・コード更新の方法
動作中のログを続けて確認する場合は、次のコマンドを使います。
$ sudo journalctl -u discord-bot -f
Ctrl+Cでログ表示を終了できます。この操作でBotは停止しません。
Botを停止・再起動するコマンドはこちらです。
# 停止
$ sudo systemctl stop discord-bot
# 再起動
$ sudo systemctl restart discord-bot
コードを更新するときは、Botを停止してファイルを差し替え、再び起動します。追加ライブラリがあれば、起動前に仮想環境へインストールしてください。
$ sudo systemctl start discord-bot
Pythonコードやトークンの変更は、再起動で読み込まれます。.serviceファイルを変更した場合は、先にdaemon-reloadも実行してください。
起動できないときの確認ポイント
起動に失敗したら、まずログを確認します。
$ sudo journalctl -u discord-bot -n 100 --no-pager
よくある確認ポイントは次のとおりです。
ModuleNotFoundError:仮想環境に必要なライブラリが入っているかPermissionError:専用ユーザーが対象ファイルを読み書きできるかKeyError: 'DISCORD_TOKEN':設定ファイルの変数名が合っているか- ログイン失敗:トークンやネットワーク接続に問題がないか
- 起動ファイルが見つからない:
ExecStartのパスが正しいか
失敗を繰り返して起動制限がかかった場合は、原因を修正してから次を実行します。
$ sudo systemctl reset-failed discord-bot
$ sudo systemctl start discord-bot
常時稼働させる場合も、設定して終わりではありません。コード更新後やサーバー再起動後には、ログとDiscord上の動作を確認しておくと、問題に気づきやすくなります。
最後に
_____________________
現在DiscordBotの制作・運用・デバック依頼を受け付けております。
「この機能だけがほしいのに他の機能が多すぎる」「サーバーの専属BOTを作って欲しい」「デバックをしたいが時間がない」「BOTの紹介記事を書いてほしい!」と思っていて、依頼をしたい方は以下のDiscordサーバーへお越しください。
また、coconalaでも受け付けております。お気軽にご相談ください。

※DiscordBotの制作・デバック依頼に関しましては、5000円からの有料で受け付けています。
無償依頼は基本受け付けておりませんのでご了承ください。



コメント