デプロイと注意点
Bot は常時稼働が前提。デプロイ先の選び方と、本番運用で気をつけるポイントまとめ。
デプロイ先の選び方
| サービス | 向き不向き | 料金感 |
|---|---|---|
| Railway | GitHub 連携で簡単。常時稼働 OK | $5/月~ |
| Fly.io | 軽量 VM。グローバルリージョン | 無料枠あり |
| Render | ヒロク風。Background Worker サービス | $7/月~ |
| VPS(さくら/Vultr/Hetzner) | 自由度最大。systemd で管理 | $5/月~ |
| Cloudflare Workers | HTTP Interactions のみ。Gateway Bot は不可 | 無料枠厚い |
| Heroku(無料廃止) | 選ばない | — |
音声 bot: VPS / Railway / Fly。サーバレスは UDP/WebSocket の制約で動かない。
軽量コマンド bot: Cloudflare Workers + HTTP Interactions が無料枠で運用可能。
環境変数の管理
- 本番では絶対に
.envをデプロイしない。各サービスのシークレット管理に DISCORD_TOKEN、DISCORD_APP_ID、DATABASE_URL等- ローカル開発と本番で異なる Botを使うと安全(dev用 / prod用 で2つ)
プロセスマネージャ
VPS の場合 — systemd
/etc/systemd/system/mybot.service
[Unit]
Description=Discord Bot
After=network.target
[Service]
Type=simple
User=mybot
WorkingDirectory=/home/mybot/app
EnvironmentFile=/home/mybot/app/.env
ExecStart=/usr/bin/node dist/index.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl enable mybot
sudo systemctl start mybot
sudo journalctl -u mybot -f
PM2(Node.js プロセスマネージャ)
npm install -g pm2
pm2 start dist/index.js --name mybot
pm2 save
pm2 startup # OS 再起動時に自動起動
ロギング
console.log+ journalctl / Docker logs で十分なケースが多い- 規模が大きくなったら pino や winston + 外部ログ(Logtail / Better Stack / Datadog)
- Sentry でクラッシュ・エラー監視
レート制限と再接続
- discord.js は自動で再接続する。普通は何もしなくてよい
- レート制限も内部でキューイングされる
- Sharding(2,500 サーバー超)は
ShardingManagerで自動分割 client.on("rateLimit", ...)でレート制限を観測できる
データベース
小規模: SQLite(better-sqlite3)
中〜大規模: PostgreSQL + Prisma / Drizzle ORM
Discord の ID はBigInt(snowflake)。文字列で扱うのが安全。
テスト
Bot は外部依存が大きいのでテストが難しい。
- ユニットテスト: ロジックを純粋関数に切り出して Jest / Vitest で
- モック: discord.js のオブジェクトを mock する(型は緩めに)
- E2E: 開発用の dev サーバ + dev bot で実際に動かす
セキュリティ
- トークンを絶対漏らさない。漏れたら即 Reset
- 権限は最小限に。
Administratorは避ける - SQL インジェクションに注意(ユーザ入力をそのまま SQL に乗せない)
- 外部 API への中継を Bot にやらせる時、自分のサーバーが踏み台にされないか考える
- 2FA を Discord アカウントに付ける(Bot 管理に必須)
大規模 bot で気をつけること
- Sharding: 2,500+ サーバーで必須
- キャッシュ: 全メンバーをキャッシュすると死ぬ。必要な時 fetch で十分
- Verified Bot: 100 サーバー以上は Discord の認証申請が必要
- Privileged Intents 申請: Message Content / Members / Presence は審査が要る
- 監視: API 5xx・Gateway disconnect・heap usage を Datadog 等で
よくある落とし穴
- "Used disallowed intents": Portal で Privileged Intent を有効化
- スラッシュコマンドが出ない: deploy-commands を再実行 / Guild ID 確認 / scope に
applications.commands - "interaction failed": 3 秒以内に応答していない。
deferReplyを使う - ボタンが反応しない:
customIdの typo / 古いメッセージで bot 再起動後 - 埋め込みが表示されない:
Embed Links権限がない - 権限不足エラー (50013): bot の権限を Channel Override で確認
- 音声 bot が静か: FFmpeg / 暗号化ライブラリの未インストール、selfDeaf=true
- 無限再帰でループ:
msg.author.botでループ防止
運用チェックリスト
- ✓ 本番トークンと開発トークンが別
- ✓
.envが.gitignore - ✓ プロセスが落ちても自動再起動(systemd / PM2)
- ✓ ログが見られる(journalctl / Logtail)
- ✓ 例外がクラッシュにならない(try/catch / process.on("unhandledRejection"))
- ✓ レート制限・disallowed intents の監視
- ✓ 重要操作は audit log を取る
- ✓ Discord 規約・自動化ルールを守る
参考リンク
discord.js 公式 / discord.js ガイド / Discord API Docs / Rate Limits