aiogramでTelegramボットを書き、ローカルでテストし、動きます。今度は、ノートPCを閉じても眠らないどこかに住まねばなりません。小さなVPSが自然な住処 — でもSSHセッションの python bot.py と、クラッシュ、再起動、接続断を通して実際に上がったままのボットとの間には隔たりがあります。
これが本番版です:virtualenv、コードから外したトークン、ボットを自分で蘇らせるsystemdサービス、そして誰もがいずれ尋ねる問い — pollingかwebhookか? — への曇りのない答え。
なぜノートPCで動かすだけではだめか
ボットにはTelegramへの安定したアウトバウンド接続が要ります。ノートPCはスリープし、更新のため再起動し、ネットワーク間を跳ねます — その一つ一つがボットを落とし、ユーザーは沈黙の壁にぶつかります。VPSはその接続を四六時中保ちます。それがマシンから移す全体の理由で、Discordボットもサーバーに属するのと同じ理由です。
最小限のボットで可能な限り速い「オンラインにする」道が欲しいだけなら、Telegramボットをホストするウォークスルーがそれを扱います。この記事は一段深く行きます:aiogram、安全なトークンの扱い、そしていつスケールするかを知ること。
ボット、virtualenvの中で
SSHで入り、ボットを自分のvenvの中で隔離しましょう — パッケージをシステム全体に入れないこと、後でアップグレードと掃除がぐちゃぐちゃになります:
sudo apt update && sudo apt install -y python3-venv
mkdir ~/tgbot && cd ~/tgbot
python3 -m venv venv && source venv/bin/activate
pip install -U aiogram
トークンをハードコードした文字列ではなく環境から読む、最小限のaiogram 3ボット:
# bot.py
import asyncio, logging, os
from aiogram import Bot, Dispatcher
from aiogram.types import Message
from aiogram.filters import CommandStart
logging.basicConfig(level=logging.INFO)
dp = Dispatcher()
@dp.message(CommandStart())
async def start(m: Message):
await m.answer("Alive and running on a VPS.")
async def main():
bot = Bot(os.environ["BOT_TOKEN"])
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
トークンをコードから外す
BotFatherのトークンを決して bot.py に貼らないこと — 公開リポへの一度のプッシュで漏れます。代わりにroot読み取り可能なenvファイルに置きます:
sudo tee /etc/tgbot.env >/dev/null <<'EOF'
BOT_TOKEN=123456:your-token-from-botfather
EOF
sudo chmod 600 /etc/tgbot.env
漏れたトークンはBotFatherの /revoke 一つで直せます — でも共有マシンで漏れたそれ以外の何かはもっと悪い。ボット専用のVPSは、正直、日常のノートPCよりトークンにとって安全な住処です:漏れても、回すのはトークン一つで、設定全体ではありません。
生かし続ける部分:systemd
これが、動くボットと動き続けるボットを分けるものです。サービスを作ります:
# /etc/systemd/system/tgbot.service
[Unit]
Description=Telegram bot (aiogram)
After=network-online.target
Wants=network-online.target
[Service]
User=botuser
WorkingDirectory=/home/botuser/tgbot
EnvironmentFile=/etc/tgbot.env
ExecStart=/home/botuser/tgbot/venv/bin/python bot.py
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
非rootユーザー(上の botuser)で動かすこと、rootではなく — ボットが侵害されても、箱の中に閉じ込めたいのです。それから:
sudo systemctl daemon-reload
sudo systemctl enable --now tgbot
Restart=always と RestartSec=3 は、クラッシュ — Telegramからの悪い更新、未処理の例外、OOM — がボットを、あなたが気づくまで死なせておく代わりに3秒で戻すことを意味します。ライブで見る:
journalctl -u tgbot -f
それがあなたのログ設定の全部です。回すログファイルもなく、追加ツールもなし — journaldがすでに持っています。
ダウンタイムの劇なしで更新する
コードを変えるかaiogramを上げるとき:
cd ~/tgbot && source venv/bin/activate
pip install -U aiogram # ライブラリをアップグレードするなら
sudo systemctl restart tgbot
journalctl -u tgbot -n 30 --no-pager # きれいに戻ったか確認
再起動はボットを1〜2秒ちらつかせます。pollingボットにはそれはユーザーに見えません — Telegramが更新をキューし、ボットが再接続すると届けます。
polling対webhook — 正直な版
これが人々が考えすぎる決定です。素直な版はこう:
polling(start_polling、上のコードが使うもの)は、長寿命の接続でボットにTelegramへ「何か新しい?」と尋ねさせます。アウトバウンドのインターネット以外何も要らず — ドメインも、TLSも、開いたインバウンドポートもなし。NATの後ろで問題なく動きます。ボットの圧倒的多数にはこれが正しく、ここで止まるべきです。
webhookはTelegramが更新をあなたに押すので、公開HTTPSエンドポイントを晒さねばなりません。それにはドメインと到達可能なインバウンドポートが要り — つまり専用の公開IPか前段のリバースプロキシか。設定が増え、壊れるものが増えます。見返りは大規模での低遅延と少ないオーバーヘッド — 数千の同時ユーザー、重い更新量。
実践的な法則:NATプランのpollingから始める。 webhookへ移るのは実際にpollingを超えて成長したときだけ — そしてそうなったら、その時こそ専用IPが自分の場所を稼ぎます、そのインバウンドHTTPSエンドポイントが要るからです。
動かすのにかかる費用
pollingボットは軽い。Telegramのロングポールでアイドルしメッセージに反応するので、箱は大半待っています:
- $3 Nano(2 vCPU / 1 GB) — ほとんどのボットに、かなりおしゃべりなものでも問題なし。
- $5 Micro(2 vCPU / 2 GB) — ボットがデータベース(SQLite/Postgres)を保つ、メディアを扱う、多くのユーザーを提供するとき。
- それ以上はボット自身が本当の仕事をするときだけ — 画像処理、ローカルモデル、重いメッセージごとのロジック。
サインアップはメールのみで、BaseまたはEthereum上のUSDCまたはUSDTで払います — カードもIDもなし。カードも使えますが、オンランプに〜$27の最低額があるので、$3プランには小さな残高を一度チャージし更新にそこから引かせるほうが滑らか。CPUのみ、ドイツとフィンランドの二つのロケーション(利用できるかどうかは注文時に表示されます) — ボットには非問題、GPUや特定のリージョンが要るなら知っておく価値があります。
正直な結論
Telegramボットは自ホストできる最も安いものの一つ:$3の箱、systemdユニット、そしてpollingが、あなたがお守りしなくてもクラッシュと再起動を通してオンラインなボットを与えます。webhookとより大きなプランに手を伸ばすのは、スケールが実際に強いるときだけ — チュートリアルがwebhookを「良い」と言ったからではなく。小さな箱を取り、トークンをenvファイルに保ち、systemdに稼働時間を任せ、そして — 何より先に — 新VPSセキュリティチェックリストを走らせて箱自体を締めましょう。
あなたのをホストする準備はいい? Telegramボットはリソースをほとんど使いません — Nanoプラン(月$3)が手間なく24時間365日動かします。
コメント
まだコメントはありません。最初になりましょう。