ノートパソコンの蓋を閉じるまでは、Bot はすべてのメッセージに返信します。しかし閉じた途端、ユーザーには何の応答も届きません。月数ドルの小さな VPS で解決できます。Telegram Bot に最適な VPS は、更新を取得する方法次第です。Bot が Telegram に問い合わせるか、Telegram が Bot に送信するかのどちらかです。
この選択によって、必要なポートと証明書、そしてパブリック IPv4 接続の必要性が決まります。
短いバージョン
- 1 台の VPS で 1 つの Bot を動かすなら、ロングポーリングを使います。ドメイン、証明書、受信ポートの開放は不要です。
- Webhook にはポート 443、80、88、8443 のいずれかでの HTTPS とパブリック IPv4 アドレスが必要です。Telegram は IPv6 では Webhook を配信しません。
- 512 MB of RAM is a workable start for one bot with no local database.
- systemd で Bot を常時稼働させます。すでにコンテナで配布している場合は Docker の再起動ポリシーを使います。
- 表示価格だけでなく、IPv4 と RAM の余裕を基準にプロバイダーを選びます。
ポーリングか Webhook か:サーバー要件を決める選択
Telegram Bot が更新を受け取る方法は 2 つあります。ロングポーリングでは Bot が getUpdates を呼び、更新が届くかタイムアウトするまで Telegram がリクエストを保持します。そのため接続はすべて自分のサーバーから始まります。Webhook では setWebhook で一度 URL を登録すると、Telegram が各更新を HTTPS の POST で送信します。
| 要件 | ロングポーリング(getUpdates) |
Webhook(setWebhook) |
|---|---|---|
| 受信ポート | 不要。送信リクエストのみ | 443、80、88、8443 のいずれかで HTTPS |
| パブリック IPv4 | 不要 | 必要。Webhook は IPv6 非対応 |
| ドメインと証明書 | 不要 | 証明書が必要。通常はドメインを使用するが、自己署名証明書では IP を CN に指定可能 |
| プロセス | 常時稼働 | HTTPS リクエストに常時応答 |
Webhook の列は Telegram の Webhook 要件に基づきます。
Bot が使っている方式は、Bot API に問い合わせると確認できます。
curl "https://api.telegram.org/bot<YOUR_TOKEN>/getWebhookInfo"
応答に "url":"" が含まれていれば Webhook は未設定で、ロングポーリングを使用できます。grammY の bot.start() はデフォルトでロングポーリングを行います。python-telegram-bot は run_polling() または run_webhook() を使用します。
専用 VPS で Bot を 1 つ動かすなら、私はポーリングを選びます。これは grammY の標準的な推奨でもあります。サーバーですでにリバースプロキシ(HTTPS リクエストを Bot に転送する Web サーバー)が動いている場合、複数の Bot が 1 つの HTTPS エンドポイントを共有する場合、サーバーレス環境では Webhook が適しています。その構成では、Caddy が証明書の取得と更新を行うため、cron ジョブは不要です。
短い停止ではメッセージは遅延しますが、失われません。Bot API の更新ルールによると、どちらの方式でも Telegram は Bot が受け取るまで最大 24 時間更新を保存します。また、配信を断念するまで失敗した Webhook リクエストを再試行します。
Webhook がポートを直接専有する場合、そのポートへの接続元を Telegram が公開するアドレス範囲に制限します。別のサイトも扱うリバースプロキシがポート 443 を共有している場合、制限は Webhook のパスだけに適用するか、Telegram のシークレットトークンを利用し、他の HTTPS 通信をすべて遮断しないようにします。Webhook ガイドには 2 つの送信元範囲が記載され、変更の可能性も示されています。ホストのファイアウォールに UFW を使う場合は次のようにします。
sudo ufw allow 22/tcp # keep SSH open before you enable the firewall
sudo ufw allow proto tcp from 149.154.160.0/20 to any port 443
sudo ufw allow proto tcp from 91.108.4.0/22 to any port 443
sudo ufw allow 80/tcp # if your HTTPS setup uses HTTP validation or redirects HTTP to HTTPS
sudo ufw enable
Webhook が 80、88、8443 で待ち受ける場合は 443 を変更します。これらのルールはホスト上で直接動く Bot を保護します。Docker のファイアウォール文書は公開ポートが UFW を迂回すると説明しているため、-p 443:443 で起動した Webhook コンテナには誰でも接続できます。さらに setWebhook に secret_token を設定してください。Telegram は各リクエストの X-Telegram-Bot-Api-Secret-Token ヘッダーにこの値を含めます。ハンドラーはこの値がないリクエストを拒否します。
Bot の常時稼働:systemd と Docker
Telegram Bot を 24 時間稼働させるには、クラッシュや再起動の後に起動し直す必要があります。VPS では systemd が対応し、Bot をイメージとして配布する場合は Docker も使えます。
systemd ユニットは、プログラムの起動と再起動方法を init システムに伝える短い設定ファイルです。/etc/systemd/system/telegram-bot.service を作成します。
[Unit]
Description=Telegram bot
After=network-online.target
Wants=network-online.target
[Service]
User=bot
WorkingDirectory=/opt/bot
EnvironmentFile=/opt/bot/.env
ExecStart=/opt/bot/venv/bin/python bot.py
# Node: ExecStart=/usr/bin/node bot.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
トークンはコードに埋め込まず、プロジェクトフォルダーの .env ファイルに BOT_TOKEN=... として保存し、os.environ["BOT_TOKEN"](Node では process.env.BOT_TOKEN)で読み込みます。その後、プロジェクトを配置して起動します。
sudo mkdir -p /opt/bot
sudo cp -r ~/your-bot/. /opt/bot/ # your project, after git clone or scp from your machine; include .env and requirements.txt
sudo apt install -y python3-venv # Debian/Ubuntu
sudo useradd --system --no-create-home bot
sudo chown -R bot:bot /opt/bot
sudo -u bot python3 -m venv /opt/bot/venv
sudo -u bot /opt/bot/venv/bin/pip install -r /opt/bot/requirements.txt
# Node: skip the venv and pip commands above, then run:
cd /opt/bot && sudo -u bot npm ci
sudo chmod 600 /opt/bot/.env
sudo systemctl daemon-reload
sudo systemctl enable --now telegram-bot
systemctl status telegram-bot # look for: Active: active (running)
sudo journalctl -u telegram-bot -f # follow the bot's logs
systemd.service マニュアルによると、Restart=always は正常終了でもクラッシュでも Bot を再起動し、on-failure は正常終了時には再起動しません。RestartSec=5 は再試行の間隔を設定し、WantedBy=multi-user.target と enable は起動時の自動実行を有効にします。再起動を繰り返す場合は sudo journalctl -u telegram-bot -n 50 でトレースバックを確認できます。まず BOT_TOKEN の欠落を確認してください。
Docker では 1 つのフラグで同じ設定ができます。
docker run -d --name telegram-bot --restart unless-stopped --env-file .env your-bot-image
docker logs -f telegram-bot
Compose では restart: unless-stopped と記述します。Docker の再起動ポリシー文書によると、コンテナは終了時やデーモンの再起動時に復帰しますが、手動で停止した場合は復帰しません。Docker 自体が起動時に立ち上がれば、サーバー再起動にも対応します。Debian と Ubuntu ではこれがデフォルトです。それ以外では sudo systemctl enable docker.service を実行します。
私の基準は、小さなサーバーでスクリプト 1 本なら systemd を使い、余分なデーモンをメモリに置かないことです。すでにイメージを作成したり別のコンテナを動かしたりしているなら Docker を使い、デーモンによる RAM 消費も見込みます。
どちらのツールも Bot の停止を通知してくれません。別のサーバー上の Uptime Kuma プッシュ監視なら通知できます。Bot が定期的に監視 URL を呼び出し、それが途絶えると Uptime Kuma が Telegram に通知します。
無料ホスティングと自宅サーバーの限界
Render は受信トラフィックが 15 分間ないと無料 Web サービスを休止します。Render の無料プラン文書によると、復帰には約 1 分かかります。ポーリング Bot は受信トラフィックがないため停止されます。Webhook Bot は Telegram の POST で復帰しますが、静かな時間が続いた後はコールドスタートになります。つまり Telegram Bot に無料ホスティングが使えるかは、採用する方式次第です。
grammY のガイドはサーバーレス環境を Webhook に適した選択肢として挙げています。一方、ロングポーリングには常時稼働するマシンが必要です。Fly.io は従量課金で、カード情報の登録が必要です。
Raspberry Pi や古い PC でも、本体、電源、回線が動いている間はポーリング Bot を稼働できます。自宅で Webhook を使うには、パブリックアドレスとポート転送も必要です。趣味の Bot なら、どちらの無料方式でも十分な場合があります。
VPS なら固定月額で両方の方式に対応できます。
Telegram Bot 向け VPS プロバイダー 5 社を比較
以下の表は Telegram Bot 向けの有料入門プラン 5 つを、2026 年 10 月時点の税抜きの広告月額料金で比較しています。該当する場合はキャンペーン価格を明記しています。
| プロバイダー | 入門プランの仕様 | 月額料金 | パブリック IPv4 | 請求 |
|---|---|---|---|---|
| Cloudzy | 1 vCPU(AMD EPYC)、512 MB DDR5、20 GB NVMe、転送量 1 TB | キャンペーン $2.48(通常 $4.95) | IPv6 とともに含む | 時間単位または月単位 |
| DigitalOcean | 1 vCPU、512 MiB、10 GiB SSD、転送量 500 GiB | $4 から | 含む | 秒単位(月額料金が上限) |
| Vultr | 1 vCPU、512 MB、10 GB SSD、転送量 512 GB | IPv6 のみ $2.50 から、IPv4 付き $3.50 から | $3.50 プランのみ | 時間単位または月単位 |
| Hetzner(ドイツ/フィンランド) | 2 vCPU、4 GB、40 GB SSD、転送量 20 TB | €5.49 から、VAT 別 | 追加 €0.50/月から、VAT 別(IPv6 無料) | 時間単位、月額料金が上限 |
| Linode (Akamai) | 1 vCPU、1 GB、ストレージ 25 GB、転送量 1 TB | $5 から | 含む | 時間単位または月単位 |
Vultr の IPv6 専用プランには IPv4 がなく、Hetzner の価格にも IPv4 アドレスは含まれません。IPv4 がなければ、どちらも Webhook を受信できません。
api.telegram.org には IPv6 アドレスがあるため、ポーリング Bot は IPv6 のみでも動作できます。ただし、パッケージレジストリ、Git ホスト、呼び出すすべての API など、他の接続先にも IPv6 アドレスが必要です。選択前に各ホストを確認してください。
dig +short AAAA api.telegram.org
dig +short AAAA github.com
dig +short AAAA pypi.org # repeat for every host your bot or its installs reach
結果が空なら、そのホストには IPv6 アドレスがありません。
Telegram Bot に 512 MB で足りるか?
ローカルデータベースのない Bot 1 つなら、私は 512 MB から始めます。python-telegram-bot の文書にはメモリ要件がありません。必要量は、OS、使用する場合の Docker デーモン、ローカルデータベースなど、同じサーバー上の構成で決まります。実測してください。
free -m # "available" is your headroom; the Swap row shows swap use
ps -o rss,cmd -p "$(systemctl show -p MainPID --value telegram-bot)" # bot's resident memory, in KB
docker stats --no-stream # per-container memory, if the bot runs in Docker
journalctl -k | grep -i "out of memory" # kernel OOM kills
メモリ不足(OOM)による強制終了とは、RAM を確保するためにカーネルがプロセスを終了させることです。systemd が Bot を再起動するため、ログの 1 行しか証拠が残らない場合があります。OOM 終了が発生した場合、スワップが常用される場合、またはローカルデータベースや 2 つ目の Bot を追加する前には 1 GB に増やします。
どれを選ぶか
Bot 1 つなら、パブリック IPv4 付きの 512 MB プランを選びます。そのうえで、価格、余裕、ユーザーの所在地を基準にプロバイダーを決めます。
- 現在の最安月額:Cloudzy は 50% 割引期間中 $2.48 で、IPv4 と IPv6 を含みます。
- IPv4 付きの現在の最安値:Cloudzy はキャンペーン中 $2.48。専用 IPv4 と IPv6 が含まれます。
- 1 GB of headroom for Docker or a small database: Linode, from $5 a month.
- 複数の Bot やデータベースを使い、ユーザーがヨーロッパにいる場合:プランの在庫があれば、この表で 1 ユーロあたりのリソースが最も多い Hetzner(2026 年 10 月時点では提供不可と表示されていました)。Webhook 用には IPv4 料金を加算します。
- 512 MB で多くのディスクと転送量:Cloudzy。512 MB プランの中でストレージ(他社の 10 GB に対して 20 GB NVMe)と転送量(約 500 GB に対して 1 TB)が最大で、IPv4 と IPv6 も含まれます。現在のキャンペーン価格では、比較対象の他の入門プランより安価です。
現在のキャンペーン価格では、Cloudzy はこの比較で最安の月額料金と、他の 512 MB プランより多いストレージと転送量を兼ね備えています。Cloudzy の 512 MB プランは時間課金で 14 日間の返金保証があるため、契約を決める前に数日間 Bot を稼働できます。ユーザーに最も近い拠点を選び、Cloudzy Linux VPS をデプロイして、上記の systemd ユニットを配置してください。
よくある質問
Telegram Bot を動かせる最安の VPS は?
2026 年 10 月時点で、Cloudzy の 512 MB プランが 5 社中最安で、50% 割引中は月 $2.48、専用 IPv4 と IPv6 付きです。通常価格は月 $4.95 です。Vultr の IPv6 のみのプランは少し高めの $2.50 からです。
Telegram Webhook に HTTPS が必要なのはなぜ?
Webhook ガイドによると、Telegram はどのポートでも Webhook に SSL/TLS を要求します。平文 HTTP は拒否され、TLS 1.2 以降を受け付けます。TLS がなければ、各 POST がユーザーのメッセージを暗号化せずに送信してしまいます。Let's Encrypt 証明書のほか、setWebhook でアップロードした自己署名証明書も使えます。
Telegram Bot は RAM 512 MB で動く?
ローカルデータベースのない Bot 1 つなら、通常は動きます。カーネルログでメモリ不足による終了を監視し、発生した場合やデータベースを追加する際は 1 GB に増やしてください。
再起動後も Telegram Bot を動かすには?
sudo systemctl enable --now telegram-bot で systemd サービスを有効にするか、--restart unless-stopped を指定してコンテナを実行し、Docker が起動時に立ち上がるよう docker.service を有効にします。
Telegram は IP アドレス単位で Bot のレートを制限する?
Telegram の制限に関する Bot FAQでは、Bot ごと、チャットごとに制限が説明されています。サーバー移転を制限回避の手段と考えるべきではありません。上限を超えると API は HTTP 429 と retry_after の値を返します。その秒数だけ待ってから再試行してください。
Telegram Bot のサーバーリージョンはどこを選ぶべき?
ユーザーと Bot の接続先サービスに最も近い場所を選び、各候補から curl -o /dev/null -s -w '%{time_connect}\n' https://api.telegram.org で接続時間を測定してください。
ディスカッション
コメント
ログインしてディスカッションに参加してください。