render を使った Discord Bot の構築と運用（無料）

## はじめに
無料で使えるホスティングサービスである [Render](https://render.com) と [Discord.py](https://github.com/Rapptz/discord.py)を用いた、Discord Bot の構築と運用についてまとめてみました。

## Render とは
[Render](https://render.com) とは、ウェブサイトやアプリケーションをホストするためのクラウドホスティングサービスです。静的サイト、Docker コンテナ、サーバーレス関数、データベース、バックエンド API など、さまざまな種類のアプリケーションをホスティングできます。いわゆる PaaS（Platform as a Service）と呼ばれるサービスに分類されます。また、GitHub などと連携することで、簡単にソースコードのデプロイができます。主な対応言語として、Node.js, Python, Ruby, Elixir, Go, Rust などがあります。
Render には、無料枠があるため、個人開発者や小規模のプロジェクトにも利用しやすくなっています。また従量課金制であり、トラフィックやリソースの使用量に応じて課金されます。さらに、Render は高速かつ安全な CDN（コンテンツ配信ネットワーク）を提供しているため、世界中のユーザーに高速で安定したアプリケーションの提供が可能です。

## 環境
* Raspberry Pi 4 Model B
    * CentOS Stream 8
        * Python 3.11.0
            * discord.py 2.1.1
* [Render](https://render.com)
* [Uptime Robot](https://uptimerobot.com)

## 導入

### Bot アカウントの作成
<a href="https://discord.com/developers">Discord Developer Portal</a> より Bot アカウントを作成しましょう。詳細な手順については既にまとまっている記事があるため省きます。以下の記事を参考にして下さい。
実装においてアクセストークンが必要になります。メモしておきましょう。

https://qiita.com/1ntegrale9/items/cb285053f2fa5d0cccdf

### Render アカウントの作成
[Render](https://render.com) にアクセスし、[GET STARTED FOR FREE] をクリックします。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115291/ed61f99d-dd0c-fde2-17d5-a4a28786656a.png)
GitHub 連携ができるので、GitHub 連携を連携して下さい。`Render by Render would like permission to:`と表示されるので、`Authorize Render` を選択して下さい。その後、メールアドレス認証が求められるのでメールアドレスを入力し、[COMPLETE SIGN UP] を選択して下さい。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115291/c148646f-09ed-2e3b-17b9-db451dba0509.png)
`Activate your Render account` というメールが届くのでリンクを踏んで認証して下さい。これでアカウント作成完了です。
今回使用するのは Web Services になります。性能は以下の通りです。かなりしょぼいですね。稼働時間にも制限があり Bot も一つまでしか運用できません。

* 0.1 CPU
* 512 MB の RAM
* 月当たり 750 時間の稼働時間
* 100 GB のアウトバウンド

また、この Web Services では15分レスポンスがないと自動的にダウンしてしまいます。そこで、Bot とは別に Web サーバを立ち上げ、[Uptime Robot](https://uptimerobot.com) を用いて、定期的にレスポンスを送ることにします。

>Web Services on the free instance type are automatically spun down after 15 minutes of inactivity. When a new request for a free service comes in, Render spins it up again so it can process the request.

https://render.com/docs/free

また、Render では GitHub のリポジトリに変更があった場合、自動的に再デプロイしてくれる機能があります。

### デプロイ
アカウントの準備ができたのでいよいよデプロイに移っていきます。必要なファイルを GitHub のリポジトリに追加します。必要なファイルは `main.py`, `keep_alive.py`, `requirements.txt`, `Dockerfile` になります。一例として、投稿されたメッセージに自動的にリアクションする Bot を考えてみましょう。各々動かした Bot のソースコードに置き換えてください。`keep_alive()` で Web サーバを立ち上げています。
```python:main.py
import discord
import os
from keep_alive import keep_alive

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

@client.event
async def on_ready():
    print('ログインしました')

@client.event
async def on_message(message):
    emoji ="👍"
    await message.add_reaction(emoji)

TOKEN = os.getenv("DISCORD_TOKEN")
# Web サーバの立ち上げ
keep_alive()
client.run(TOKEN)
```
続いて `keep_alive.py` ファイルになります。Flask を用いて Web サーバを立ち上げています。
```python:keep_alive.py
from flask import Flask
from threading import Thread

app = Flask('')

@app.route('/')
def home():
    return "I'm alive"

def run():
    app.run(host='0.0.0.0', port=8080)

def keep_alive():
    t = Thread(target=run)
    t.start()
```
`requirements.txt` ファイルについては `pip freeze` コマンドより必要なライブラリを記載して下さい。
```text:requirements.txt
discord.py==2.1.1
Flask==2.2.3
```
最後に `Dockerfile` になります。以下のように作成して下さい。
```text:Dockerfile
FROM python:3.11
WORKDIR /bot
COPY requirements.txt /bot/
RUN pip install -r requirements.txt
COPY . /bot
CMD python main.py
```
必要なファイルを GitHub にプッシュする方法は、記事にまとめているので参考にしてみて下さい。

https://qiita.com/Pumila/items/b90b7647f39ed3ca2069

GitHub にリポジトリを用意できたら、[Render Dashboard](https://dashboard.render.com) から [New Web Services] を選択します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115291/dfb76123-0835-c7f4-39e7-e7964a1c3425.png)
この時点ではまだ、GitHub と連携できていないみたいでリポジトリが見つからないと思います（GitHub 連携でログインしたはずなんですが…）。右側から [Connect account] を選択し、GitHub と連携するか、`Public Git repository` から直接リポジトリの URL を指定しても構いません。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115291/593d6ac0-4446-be40-7387-820e5fc4c738.png)
GitHub と連携したら目的のリポジトリから [Connect] を選択して下さい（URL から直接指定する場合は、URL を入力後 [Continue] を選択して下さい）。そしたらプロジェクトの設定画面に移るので、適当に名前を入力し、[Region] として一番近いシンガポールを選択して下さい。[Runtime] は "Doker" のままで問題ありません。続いて環境変数の設定を行っていきます。スクロールしていくと、画面左下に [Advanced] があると思うので選択し、以下のように環境変数を設定して下さい。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115291/687a17e9-4e45-ac8c-258f-b6ec893e2d5b.png)
設定ができたら、[Create Web Service] を選択して下さい。自動的にデプロイが開始されます。私の環境では 80 秒程かかりました。デプロイが完了したら以下のように Web サーバの URL が表示されていると思います。この URL に Uptime Robot を用いて定期的にレスポンスを送ることにします。メモしておきましょう。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115291/67222bc1-cf4b-8980-58d4-651c45f6a587.png)


### Uptime Robot の設定
[Uptime Robot](https://uptimerobot.com) とは無料で Web サイトの死活監視をモニタリングしてくれるサービスになります。[サイト](https://uptimerobot.com)にアクセスし右上の [Register for FREE] からアカウントを作成して下さい。アカウントが作成できたら自動的に "Dashboard" ページに移動すると思います（移動しなかったらホームより [Go to Dashboard] を押して下さい）。次に左上の [Add New Monitor] から、監視対象を追加します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115291/c09cae0d-1444-4afa-f47b-128d2217a74f.png)
設定は、`Monitor Type` を `HTTP(s)`に、`Friendly Name` に適当な名前、`URL` に先程メモしておいた Render で表示された URL、`Monitoring Interval` を5分に設定（無料アカウントだと5分間隔が一番短い。アップグレードすると1分間隔に調整可能）、エラーが起きたときように `Alert Contacts To Notify` にチェックを入れ、右下の `Create Monitor` を押して完成です。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115291/204fce5f-2b84-3bcd-d135-a38820537473.png)
これで Bot を動かしている Render に、5分間隔で ping を送れるようになりました。

## ダウンタイムの検証
続いてダウンタイムの検証に移っていきます。検証期間は約3日間になります。検証に用いたファイル内容については以下記事を参考にして下さい。10秒以上応答しなかったらダウンタイムと見なしています。

https://qiita.com/Pumila/items/29f26fb349d5592046ae

ソースコードは以下になります。

https://github.com/Pumi1a/renderdowntimetest

結果として、ダウンした回数は7回あり、平均して18秒という結果になりました。そこそこ安定して稼働してくれているのではないでしょうか。

![sample-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115291/de9c3040-6bba-f817-d1d3-03bbff4b7d01.png)

ダウンタイム検証時の Discord チャンネルの様子は以下の通りです。回 "test" の削除がされていないことが分かります。これはちょうどダウンタイムと被ったためですね。2秒に1回 "test" メッセージを送っているので、ダウンタイムの時間からして、もっと多くあってもいいと思いますが、Render 上でラグがあって削除された、あるいは Raspberry Pi 上で "test" メッセージが送られなかったか、という推測ができます。Raspberry Pi 上で `journalctl -u サービス名` と実行するとエラーが発生していることが確認できました。Raspberry Pi 上で "test" メッセージが送られなかった可能性の方が高そうです。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115291/56abdc02-412c-248b-1504-8ff42d8350d3.png)


最後に `send.py` と `chk.py` のサービスログを載せておきます。`journalctl -u サービス名` でログの確認ができます。エラーが吐かれている箇所で確かに、ダウンタイムとして見なされていました。

<details><summary>サービスのログ</summary><div>

```:send.py log
Mar 27 09:28:03 localhost.localdomain systemd[1]: Started render.
Mar 27 09:28:04 localhost.localdomain send.py[5141]: [2023-03-27 09:28:04] [INFO    ] discord.client: logging in using static token
Mar 27 09:28:10 localhost.localdomain send.py[5141]: [2023-03-27 09:28:10] [INFO    ] discord.gateway: Shard ID None has connected to Gateway (Session ID: c7ac4e9ca26836dbe41e80504689ff06).
Mar 27 10:11:00 localhost.localdomain send.py[5141]: [2023-03-27 10:11:00] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 27 12:22:21 localhost.localdomain send.py[5141]: [2023-03-27 12:22:21] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 27 16:20:42 localhost.localdomain send.py[5141]: [2023-03-27 16:20:42] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 27 19:10:17 localhost.localdomain send.py[5141]: [2023-03-27 19:10:17] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 27 21:17:16 localhost.localdomain send.py[5141]: [2023-03-27 21:17:16] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 27 23:08:24 localhost.localdomain send.py[5141]: [2023-03-27 23:08:24] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 01:59:21 localhost.localdomain send.py[5141]: [2023-03-28 01:59:21] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 03:55:51 localhost.localdomain send.py[5141]: [2023-03-28 03:55:51] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 05:48:41 localhost.localdomain send.py[5141]: [2023-03-28 05:48:41] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 06:57:20 localhost.localdomain send.py[5141]: [2023-03-28 06:57:20] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 10:02:21 localhost.localdomain send.py[5141]: [2023-03-28 10:02:21] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 12:24:04 localhost.localdomain send.py[5141]: [2023-03-28 12:24:04] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 14:17:07 localhost.localdomain send.py[5141]: [2023-03-28 14:17:07] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 17:10:00 localhost.localdomain send.py[5141]: [2023-03-28 17:10:00] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 20:07:24 localhost.localdomain send.py[5141]: [2023-03-28 20:07:24] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 22:09:28 localhost.localdomain send.py[5141]: [2023-03-28 22:09:28] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 23:07:37 localhost.localdomain send.py[5141]: [2023-03-28 23:07:37] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 28 23:46:34 localhost.localdomain send.py[5141]: [2023-03-28 23:46:34] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 01:18:54 localhost.localdomain send.py[5141]: [2023-03-29 01:18:54] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 04:44:28 localhost.localdomain send.py[5141]: [2023-03-29 04:44:28] [ERROR   ] discord.client: Attempting a reconnect in 0.25s
Mar 29 04:44:28 localhost.localdomain send.py[5141]: Traceback (most recent call last):
Mar 29 04:44:28 localhost.localdomain send.py[5141]:   File "/home/web/.local/lib/python3.11/site-packages/discord/client.py", line 627, in connect
Mar 29 04:44:28 localhost.localdomain send.py[5141]:     await self.ws.poll_event()
Mar 29 04:44:28 localhost.localdomain send.py[5141]:   File "/home/web/.local/lib/python3.11/site-packages/discord/gateway.py", line 646, in poll_event
Mar 29 04:44:28 localhost.localdomain send.py[5141]:     raise ConnectionClosed(self.socket, shard_id=self.shard_id, code=code) from None
Mar 29 04:44:28 localhost.localdomain send.py[5141]: discord.errors.ConnectionClosed: Shard ID None WebSocket closed with 1000
Mar 29 04:44:35 localhost.localdomain send.py[5141]: [2023-03-29 04:44:35] [ERROR   ] discord.client: Attempting a reconnect in 0.50s
Mar 29 04:44:35 localhost.localdomain send.py[5141]: Traceback (most recent call last):
Mar 29 04:44:35 localhost.localdomain send.py[5141]:   File "/home/web/.local/lib/python3.11/site-packages/discord/client.py", line 624, in connect
Mar 29 04:44:35 localhost.localdomain send.py[5141]:     self.ws = await asyncio.wait_for(coro, timeout=60.0)
Mar 29 04:44:35 localhost.localdomain send.py[5141]:               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 29 04:44:35 localhost.localdomain send.py[5141]:   File "/usr/local/lib/python3.11/asyncio/tasks.py", line 479, in wait_for
Mar 29 04:44:35 localhost.localdomain send.py[5141]:     return fut.result()
Mar 29 04:44:35 localhost.localdomain send.py[5141]:            ^^^^^^^^^^^^
Mar 29 04:44:35 localhost.localdomain send.py[5141]:   File "/home/web/.local/lib/python3.11/site-packages/discord/gateway.py", line 372, in from_client
Mar 29 04:44:35 localhost.localdomain send.py[5141]:     socket = await client.http.ws_connect(str(url))
Mar 29 04:44:35 localhost.localdomain send.py[5141]:              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 29 04:44:35 localhost.localdomain send.py[5141]:   File "/home/web/.local/lib/python3.11/site-packages/discord/http.py", line 536, in ws_connect
Mar 29 04:44:35 localhost.localdomain send.py[5141]:     return await self.__session.ws_connect(url, **kwargs)
Mar 29 04:44:35 localhost.localdomain send.py[5141]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 29 04:44:35 localhost.localdomain send.py[5141]:   File "/usr/local/lib/python3.11/site-packages/aiohttp/client.py", line 795, in _ws_connect
Mar 29 04:44:35 localhost.localdomain send.py[5141]:     raise WSServerHandshakeError(
Mar 29 04:44:35 localhost.localdomain send.py[5141]: aiohttp.client_exceptions.WSServerHandshakeError: 520, message='Invalid response status', url=URL('wss://gateway-us-east1-b.discord.gg/?v=10&encoding=json&compress=zlib-stream')
Mar 29 04:44:38 localhost.localdomain send.py[5141]: [2023-03-29 04:44:38] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 05:52:48 localhost.localdomain send.py[5141]: [2023-03-29 05:52:48] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 09:16:39 localhost.localdomain send.py[5141]: [2023-03-29 09:16:39] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 10:06:41 localhost.localdomain send.py[5141]: [2023-03-29 10:06:41] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 13:10:38 localhost.localdomain send.py[5141]: [2023-03-29 13:10:38] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 13:51:37 localhost.localdomain send.py[5141]: [2023-03-29 13:51:37] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 16:06:18 localhost.localdomain send.py[5141]: [2023-03-29 16:06:18] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 17:42:18 localhost.localdomain send.py[5141]: [2023-03-29 17:42:18] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 19:56:45 localhost.localdomain send.py[5141]: [2023-03-29 19:56:45] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 22:58:12 localhost.localdomain send.py[5141]: [2023-03-29 22:58:12] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 29 23:56:18 localhost.localdomain send.py[5141]: [2023-03-29 23:56:18] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 30 01:13:59 localhost.localdomain send.py[5141]: [2023-03-30 01:13:59] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 30 01:57:04 localhost.localdomain send.py[5141]: [2023-03-30 01:57:04] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 30 03:50:44 localhost.localdomain send.py[5141]: [2023-03-30 03:50:44] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 30 04:12:49 localhost.localdomain send.py[5141]: [2023-03-30 04:12:49] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 30 06:46:00 localhost.localdomain send.py[5141]: [2023-03-30 06:46:00] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session c7ac4e9ca26836dbe41e80504689ff06.
Mar 30 09:30:22 localhost.localdomain systemd[1]: Stopping render...
Mar 30 09:30:22 localhost.localdomain systemd[1]: render.service: Succeeded.
Mar 30 09:30:22 localhost.localdomain systemd[1]: Stopped render.
```

```:chk.py log
Mar 27 09:28:04 localhost.localdomain systemd[1]: Started render2.
Mar 27 09:28:04 localhost.localdomain chk.py[5145]: [2023-03-27 09:28:04] [INFO    ] discord.client: logging in using static token
Mar 27 09:28:05 localhost.localdomain chk.py[5145]: [2023-03-27 09:28:05] [INFO    ] discord.gateway: Shard ID None has connected to Gateway (Session ID: a815c3b083ebebdcca5071dc6e13be07).
Mar 27 10:57:25 localhost.localdomain chk.py[5145]: [2023-03-27 10:57:25] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 27 12:37:20 localhost.localdomain chk.py[5145]: [2023-03-27 12:37:20] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 27 16:09:09 localhost.localdomain chk.py[5145]: [2023-03-27 16:09:09] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 27 18:24:26 localhost.localdomain chk.py[5145]: [2023-03-27 18:24:26] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 27 20:25:04 localhost.localdomain chk.py[5145]: [2023-03-27 20:25:04] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 27 21:10:07 localhost.localdomain chk.py[5145]: [2023-03-27 21:10:07] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 27 21:41:18 localhost.localdomain chk.py[5145]: [2023-03-27 21:41:18] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 27 22:38:39 localhost.localdomain chk.py[5145]: [2023-03-27 22:38:39] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 01:20:03 localhost.localdomain chk.py[5145]: [2023-03-28 01:20:03] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 04:23:02 localhost.localdomain chk.py[5145]: [2023-03-28 04:23:02] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 06:16:05 localhost.localdomain chk.py[5145]: [2023-03-28 06:16:05] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 06:39:19 localhost.localdomain chk.py[5145]: [2023-03-28 06:39:19] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 08:37:34 localhost.localdomain chk.py[5145]: [2023-03-28 08:37:34] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 09:23:39 localhost.localdomain chk.py[5145]: [2023-03-28 09:23:39] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 12:43:40 localhost.localdomain chk.py[5145]: [2023-03-28 12:43:40] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 16:39:40 localhost.localdomain chk.py[5145]: [2023-03-28 16:39:40] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 19:11:33 localhost.localdomain chk.py[5145]: [2023-03-28 19:11:33] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 19:49:09 localhost.localdomain chk.py[5145]: [2023-03-28 19:49:09] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 20:07:23 localhost.localdomain chk.py[5145]: [2023-03-28 20:07:23] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 28 20:47:01 localhost.localdomain chk.py[5145]: [2023-03-28 20:47:01] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 00:33:17 localhost.localdomain chk.py[5145]: [2023-03-29 00:33:17] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 01:11:33 localhost.localdomain chk.py[5145]: [2023-03-29 01:11:33] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 02:15:56 localhost.localdomain chk.py[5145]: [2023-03-29 02:15:56] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 03:07:43 localhost.localdomain chk.py[5145]: [2023-03-29 03:07:43] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 04:44:32 localhost.localdomain chk.py[5145]: [2023-03-29 04:44:32] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 05:07:05 localhost.localdomain chk.py[5145]: [2023-03-29 05:07:05] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 05:50:12 localhost.localdomain chk.py[5145]: [2023-03-29 05:50:12] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 06:17:22 localhost.localdomain chk.py[5145]: [2023-03-29 06:17:22] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 09:19:12 localhost.localdomain chk.py[5145]: [2023-03-29 09:19:12] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 11:35:27 localhost.localdomain chk.py[5145]: [2023-03-29 11:35:27] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 13:10:57 localhost.localdomain chk.py[5145]: [2023-03-29 13:10:57] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 14:48:58 localhost.localdomain chk.py[5145]: [2023-03-29 14:48:58] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 17:39:15 localhost.localdomain chk.py[5145]: [2023-03-29 17:39:15] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 19:17:23 localhost.localdomain chk.py[5145]: [2023-03-29 19:17:23] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 29 21:35:54 localhost.localdomain chk.py[5145]: [2023-03-29 21:35:54] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 30 01:16:09 localhost.localdomain chk.py[5145]: [2023-03-30 01:16:09] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 30 02:34:18 localhost.localdomain chk.py[5145]: [2023-03-30 02:34:18] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 30 05:18:13 localhost.localdomain chk.py[5145]: [2023-03-30 05:18:13] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 30 06:11:45 localhost.localdomain chk.py[5145]: [2023-03-30 06:11:45] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 30 06:26:57 localhost.localdomain chk.py[5145]: [2023-03-30 06:26:57] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 30 07:28:27 localhost.localdomain chk.py[5145]: [2023-03-30 07:28:27] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 30 09:21:29 localhost.localdomain chk.py[5145]: [2023-03-30 09:21:29] [INFO    ] discord.gateway: Shard ID None has successfully RESUMED session a815c3b083ebebdcca5071dc6e13be07.
Mar 30 09:30:22 localhost.localdomain systemd[1]: Stopping render2...
Mar 30 09:30:22 localhost.localdomain systemd[1]: render2.service: Succeeded.
Mar 30 09:30:22 localhost.localdomain systemd[1]: Stopped render2.
```

</div></details>

## 最後に
低性能の割に、比較的安定して稼働してくれているのではないでしょうか。ただ、Discord Bot を運用する上で第1候補になるかといわれると、それはないかなと思います。Railway が安定稼働してくれるので、そちらの方がいいと思います。

https://qiita.com/Pumila/items/29f26fb349d5592046ae


## 参考
[Repl.it を使った Discord Bot の構築と運用 - Qiita](https://qiita.com/Pumila/items/449d9f4d484b78e95479)
[render Docs](https://render.com/docs)