Koyeb無料でDiscordBotを立ち上げようとしてヘルスチェックで2回ハマった話
1. はじめに
Discord Botを無料で24時間運用したい――そんなときに便利なのが、クラウドPaaSの「Koyeb」。
無料枠でもDockerイメージをデプロイでき、Python製のBotも簡単に動かせます。
しかし、いざ運用してみると「一晩経つとBotが止まっている」「Instance stoppedのエラーが出る」など、思わぬ落とし穴が…。
本記事では、KoyebでDiscord Botを安定運用するために実際にハマったポイントと、その解決策をまとめます。
読者ターゲット
- 無料でDiscord Botを運用したい人
- Koyebにデプロイしようとしてハマっている人
- 一回ちゃんとデプロイできたぽいのに時間が経つとダメだな〜となっている人
2. 問題①:ヘルスチェックエラー
「Instance stopped」エラーの発生
KoyebにBotをデプロイしてしばらくは動くものの、翌朝見ると「Instance stopped」がログに出てBotが死んでいることがありました。
Bot自体は1日1回だけ通知を送るだけのシンプルなもの。
なぜ止まるのか、最初は全く分かりませんでした。(ログも出ず突如止まるんですよね。)
ヘルスチェックが通らない原因
調べてみると、Koyebの無料プランでは「ヘルスチェック」が自動で有効になっており、
デフォルトで8000番ポートにHTTPリクエストが飛ばされます。
このヘルスチェックに応答しないと「unhealthy」と判定され、インスタンスが自動で停止されてしまう仕様です。
つまり、Bot本体とは別にHTTPサーバーを立てて、ヘルスチェックに応答する必要があったのです。
公式サイトでも、
ヘルスチェック用のエンドポイントを用意すること」が推奨されています。
If you are deploying an HTTP server, like an API or a web application, we recommend that you define custom HTTP health checks on the relevant ports.
3. 問題①の解決方法:ヘルスチェックサーバーの追加
Flaskでヘルスチェック用エンドポイントを作成
Bot本体とは別に、Flaskなどの軽量Webフレームワークで「/」や「/health」などのエンドポイントを用意します。
サーバ起動用クラス
class HealthCheckServer:
def __init__(self, host="0.0.0.0", port=8000):
self.host = host
self.port = port
self.thread = None
def start(self):
def run():
app = Flask(__name__)
@app.route("/")
def health():
return "OK", 200
app.run(host=self.host, port=self.port)
self.thread = threading.Thread(target=run, daemon=True)
self.thread.start()
Botのエンドポイント
from healthcheck import HealthCheckServer
@bot.event
async def on_ready():
await bot.tree.sync()
scheduler = Scheduler(bot)
scheduler.start()
⇩こちらの記事を参考に実装しました。
PythonのWebフレームワークには詳しくないのですが、より軽量っぽかったのでFlaskを選びました。
ヘルスチェックの成功
上記実装の上でデプロイすると、ヘルスチェックが通るようになりました。この時、Koyebの「Instance is healthy. All health checks are passing.」という表示が出ます。
Koyebのサービス画面上には、こういうマークが出ているはず。(紫部分はIDなので隠しています)

4. 問題②:Sleeping状態の回避
Koyebでヘルスチェックを通しても、しばらく外部からのアクセスがないとインスタンスが「Sleeping」状態になり、Botが一時停止してしまうことがあります。これは無料プランの仕様で、一定時間リクエストがないと自動的にスリープしてしまうためです。
公式サイトより引用
They scale down to zero when they don’t receive any traffic for 1 hour.
問題②の解消:cron-job.orgを使った定期起動設定
この問題を回避するために、外部サービス「cron-job.org」を利用します。cron-job.orgは、指定したURLに定期的にGETリクエストを送ってくれる無料サービスです。
30分ごとのGETリクエスト設定
- cron-job.orgに無料登録
- 新規ジョブ作成で、Koyebのヘルスチェック用エンドポイント(例: https://<your-app>.koyeb.app/)を指定
- 実行間隔を「30分ごと」などに設定
これで、Koyeb側のインスタンスが定期的にアクセスされるため、Sleeping状態を防ぎ、Botが24時間稼働し続けます。
5. 実際の動作確認
デプロイ後のログ確認
Koyebの管理画面でデプロイ後のログを確認し、
- Flaskサーバーが8000番ポートで起動しているか
- Discord Botが正常に起動しているか
をチェックします。
Botの正常動作確認
Botが指定した時間にメッセージを送信できていればOKです。
6. まとめとベストプラクティス
- Koyebの無料プランでDiscord Botを運用する場合、ヘルスチェック用のHTTPサーバーを必ず用意する
- cron-job.orgなどの外部サービスで定期的にアクセスを送ることで、Sleeping状態を防げる
- 無料枠の制限や仕様変更には注意し、公式ドキュメントも随時チェックする
Discussion