【Linux】Python製Discord Botをuv+Docker Composeで常時稼働させる

Bot

Pythonで作ったDiscord Botを、自宅サーバーやVPSで動かしたいとき、起動方法やライブラリの管理に迷うことがあります。

今回は、uvでPythonの環境を管理し、Docker ComposeでBotを常時稼働させる方法を紹介します。Dockerは導入済みとして、ファイルの作成から起動、更新まで進めていきます。

スポンサーリンク

Dockerとuvを使うメリット

Dockerは、アプリと実行環境をまとめて動かすための仕組みです。

Botごとに環境を分けられるので、別のアプリで使うライブラリとの競合を減らせます。

また、DockerfileにPythonのバージョンや起動方法を残せるため、サーバーを移すときも環境を用意しやすくなります。Docker Composeを使えば、起動や停止、再起動の設定も一つのファイルにまとめられます。

uvは、Pythonのライブラリや仮想環境を管理するツールです。

ライブラリの導入が速いことに加えて、必要なライブラリを pyproject.toml 、具体的なバージョンをuv.lockで管理できます。同じロックファイルを使えば、開発環境とサーバー側でライブラリのバージョンをそろえやすくなります。

ただし、Dockerを使っても、サーバーの電源やネット接続が切れればBotは止まります。常時稼働には、サーバー自体を動かし続ける必要があります。

作業前に確認すること

今回はLinuxサーバー、Python 3.12、discord.pyを使います。Botの作成とサーバーへの招待は済ませておいてください。

Dockerが未導入の場合は、Docker Engineの公式インストールページから、使っているOSの手順に進んでください。

まず、次のコマンドでDockerとComposeを確認します。

docker --version
docker compose version

Composeが使えない場合は、公式のCompose導入手順を確認してください。

作業する端末にはuvも必要です。未導入の場合は、uvの公式インストールページに沿って導入します。

uvでBotのプロジェクトを用意する

次のコマンドでプロジェクトを作成し、discord.pyを追加します。

uv init --python 3.12 discord-bot
cd discord-bot
uv add discord.py

pyproject.tomlとuv.lockが作られます。Docker側でも使用するので、両方を残しておきましょう。すでにuvで管理しているBotなら、既存のプロジェクトで進められます。

動作確認用として、main.pyを次の内容にします。

import os
import discord

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


@client.event
async def on_ready():
    print(f"ログインしました: {client.user}", flush=True)


client.run(os.environ["DISCORD_TOKEN"])

この例はログイン確認だけを行います。既存のBotを動かす場合は、そのコードを使い、トークンを環境変数から読み取るようにしてください。

スポンサーリンク

トークンを.envに保存する

プロジェクト内に.envを作成します。

DISCORD_TOKEN=ここにBotのトークンを入力

トークンはBotにログインするための情報です。コードへ直接書かず、GitHubやブログ、スクリーンショットにも載せないようにしましょう。

Gitを使う場合は、.gitignoreにも追加します。

.env
.venv/
__pycache__/

なお、今回のコードは.envを直接読みません。あとでComposeがファイルの内容を環境変数として渡します。

Dockerfileを作成する

続いて、Dockerfileを作成します。

FROM python:3.12-slim-bookworm

COPY --from=ghcr.io/astral-sh/uv:0.12.23 /uv /bin/uv

WORKDIR /app
ENV PYTHONUNBUFFERED=1

COPY pyproject.toml uv.lock ./
RUN uv sync --locked --no-dev --no-install-project --no-cache \
    --python /usr/local/bin/python

COPY . .

CMD ["/app/.venv/bin/python", "main.py"]

ここではuvのバージョンを固定しています。更新する場合は、使うバージョンを確認して変更してください。

--lockedは、pyproject.tomlとuv.lockが合わない場合に処理を止める設定です。--no-devは開発用の依存グループを除き、--no-install-projectはBot自身をパッケージとしてインストールせず、必要なライブラリを導入します。

先にライブラリを導入してからコードをコピーすることで、コードだけの変更では、以前のライブラリ導入結果を再利用しやすくなります。

さらに、.dockerignoreを作成します。

.env
.venv/
.git/
__pycache__/
*.pyc

これでトークンや手元の仮想環境を、Dockerイメージに含めずに済みます。

Docker Composeで起動を設定する

compose.yamlを作成します。

services:
  bot:
    build: .
    env_file:
      - .env
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

env_fileでトークンを渡し、restart: unless-stoppedでBotの終了後に自動再起動させます。手動で停止した場合は、Dockerが再起動しても自動では起動しません。

ログには容量とファイル数の上限を設定しています。通常のDiscord Botは外向きに接続するため、この例ではポートを公開する設定は不要です。

ここまでで、主に次のファイルがそろいます。

  • main.py
  • pyproject.tomlとuv.lock
  • Dockerfileとcompose.yaml
  • .env、.gitignore、.dockerignore

Botを起動して確認する

プロジェクトのフォルダーで実行します。

docker compose up -d --build
docker compose ps
docker compose logs -f --tail=100 bot

--buildでイメージを作成し、-dでバックグラウンド起動します。SSH接続を終了しても、サーバー側のBotは動き続けます。

ログに「ログインしました」と出て、Discord上でオンラインになれば接続できています。ログ表示はCtrl + Cで終了できます。この操作ではBotは停止しません。

<トークンを表示せず、Botのログイン成功を確認できるターミナル画面>

サーバーの再起動後も動かすには、Docker自体の自動起動も必要です。systemdを使う一般的なLinux環境では、次のように設定します。

sudo systemctl enable --now docker

スポンサーリンク

コードや設定を変更したときの操作

今回の構成では、コードをイメージに含めています。main.pyを変更したら、もう一度ビルドして反映します。

docker compose up -d --build

ライブラリを追加した場合も、uv addで更新したpyproject.tomlとuv.lockをそろえて、同じコマンドを実行します。

.envだけを変更した場合は、コンテナを作り直します。

docker compose up -d --force-recreate

docker compose restartだけでは、変更した環境変数は反映されません。

停止と再開には、次のコマンドを使います。

docker compose stop
docker compose up -d

起動できないときは、まずログを確認しましょう。トークンの間違いや、コードのエラーが見つかることがあります。自動再起動はプログラムの不具合を直す機能ではありません。

また、SQLiteなどでデータを保存するBotは、保存先をボリュームとして設定する必要があります。コンテナ内だけに保存すると、作り直したときにデータが失われるためです。

uvでライブラリを管理し、Composeに起動設定をまとめておけば、Botの更新やサーバー移行の手順をそろえやすくなります。起動確認後も、必要に応じてログや保存データを確認しながら運用していきましょう。

最後に

_____________________

現在DiscordBotの制作・運用・デバック依頼を受け付けております。

「この機能だけがほしいのに他の機能が多すぎる」「サーバーの専属BOTを作って欲しい」「デバックをしたいが時間がない」「BOTの紹介記事を書いてほしい!」と思っていて、依頼をしたい方は以下のDiscordサーバーへお越しください。

Discordサーバー「ゆーたの開発ラボ」に参加しよう!
Discordでゆーたの開発ラボコミュニティをチェック! 140人のメンバーと交流し、無料の音声・テキストチャットを楽しみましょう。

また、coconalaでも受け付けております。お気軽にご相談ください。

ご要望に沿ったDiscord Botを制作します 1000サーバー超導入Botの開発経験有|欲しい機能を形に! | ココナラ
「自分のDiscordサーバー専用のBotが欲しい」「既存のBotでは欲しい機能が見つからない」「アイデアはあるけれど、自分でプログラムを書くのは難しい」そんな...

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

コメント

タイトルとURLをコピーしました