Deploy a railway python bot that never sleeps — port binding, health checks, self-ping, and crash recovery using StayPresent.
在 Railway 上使用 StayPresent 執行 Python Bot 而不休眠
Railway 可自動偵測 Python 專案,並在幾分鐘內完成部署,但 railway python bot — 例如 Discord bot、Telegram bot 或爬蟲 — 仍會遇到每個 PaaS 都會出現的核心問題:平台期望有一個面向 HTTP 的程序,而你的 bot 事件迴圈或閘道連線並不會自然提供這樣的程序。本指南將介紹如何部署一個在 Railway 上保持線上的 bot,並使用 StayPresent 來填補這項空缺。
目錄
- Railway 如何偵測並執行 Python 應用程式
$PORT要求- 設定 StayPresent
- Railway 儀表板中的健康檢查
- 針對對閒置敏感方案的自我 ping
- 當機恢復
- 完整可運作範例
- 最佳實踐
- 常見錯誤
- 常見問題
- 結論
Railway 如何偵測並執行 Python 應用程式
Railway 可從 requirements.txt(或 pyproject.toml)自動偵測 Python 專案,並透過 Nixpacks 自動為其建置容器,無需 Dockerfile。接著會啟動你的應用程式,並期望它綁定 Railway 透過 PORT 環境變數指定的連接埠,以便其自身的路由和健康檢查可以存取。
$PORT 要求
這是幾乎所有現代 PaaS 都採用的相同模式:從環境讀取 PORT,而非硬式編碼。
import os
import staypresent
staypresent.run(
"bot.py",
port=int(os.getenv("PORT", 8080)),
)
Enter fullscreen mode Exit fullscreen mode
如果你的 bot 完全沒有綁定此連接埠 — 這對於 Discord 或 Telegram bot 來說是正常且預期的行為 — 即使你的 bot 本身可能運作正常,Railway 的健康檢查(如果已啟用)仍會將部署標記為不健康。
設定 StayPresent
安裝 production 額外套件,讓 Waitress 處理服務,而非 Flask 的開發伺服器:
pip install staypresent[prod]
Enter fullscreen mode Exit fullscreen mode
你的 main.py:
import os
import staypresent
staypresent.web.json({
"status": "running",
"service": "my-telegram-bot",
})
staypresent.run(
"bot.py",
port=int(os.getenv("PORT", 8080)),
)
Enter fullscreen mode Exit fullscreen mode
Railway 的啟動指令僅為:
python main.py
Enter fullscreen mode Exit fullscreen mode
Railway 儀表板中的健康檢查
如果你已為服務啟用 Railway 的健康檢查功能,可以將其指向 StayPresent 內建的 /health 端點,該端點一律會回傳 {"status": "ok"} — 無論你在根路由設定了什麼:
staypresent.web.json({"status": "running"})
# /health still returns {"status": "ok"} regardless
Enter fullscreen mode Exit fullscreen mode
這將平台層級的健康監控與你在 / 提供給人類或自身工具的自訂狀態酬載分開。
針對對閒置敏感方案的自我 ping
是否適用基於閒置的休眠,取決於你特定的 Railway 方案和設定 — 在假設任何行為之前,請務必先查看 Railway 目前的定價和使用文件。如果你的部署確實適用,staypresent.cron() 會針對你自己的公開 URL 產生對外流量,以避免被視為閒置:
import staypresent
staypresent.cron(
"https://my-app.up.railway.app",
interval=240,
)
Enter fullscreen mode Exit fullscreen mode
與任何平台一樣,這必須指向實際的公開 URL — ping 0.0.0.0 或 127.0.0.1 永遠不會離開機器,因此對閒置偵測沒有任何影響。
當機恢復
Bot 可能因各種原因當機,而 Railway 不會自動重新啟動在容器 內部 死亡的子程序,除非容器本身退出。StayPresent 直接處理此內部層級:
staypresent.run(
"bot.py",
port=int(os.getenv("PORT", 8080)),
restart_on_crash=True,
max_restarts=5,
restart_delay=2.0,
restart_reset_after=60.0,
)
Enter fullscreen mode Exit fullscreen mode
如果最終耗盡了重新啟動次數,StayPresent 會以 bot 原本的退出代碼退出整個程序 — 讓 Railway 自己的部署重新啟動政策作為最後的後盾。
完整可運作範例
import os
import staypresent
staypresent.web.json({"status": "running"})
staypresent.cron("https://my-app.up.railway.app", interval=240)
staypresent.run(
"bot.py",
port=int(os.getenv("PORT", 8080)),
threads=8,
restart_on_crash=True,
max_restarts=5,
)
Enter fullscreen mode Exit fullscreen mode
最佳實踐
- 一律動態讀取
PORT— Railway 會為每次部署指定連接埠,且在不同環境中可能有所不同。 - 如果你的根路由提供自訂內容,請將任何設定的健康檢查指向
/health而非/。 - 對於任何接收真實流量的部署,請務必安裝
prod額外套件,而不僅是保持連線的 ping。
常見錯誤
-
硬式編碼
port=8080而非讀取os.getenv("PORT", 8080)— 這在某些設定中可能有效,但在其他情況下可能靜默失敗,視 Railway 的設定方式而定。 - 假設 Railway 的休眠行為與 Render 相同。 各平台的政策不同,且會隨時間改變 — 請查閱 Railway 自己的文件以確認目前行為,而非自行假設。
- 因為「Railway 反正會重新啟動當機的部署」而跳過當機恢復。 Railway 自己的重新啟動政策是在容器層級運作;bot 子程序在仍在執行的容器內部當機,是另一種失敗模式,StayPresent 會直接處理。
常見問題
Railway 是否需要 Dockerfile?
不需要 — Railway 可透過 Nixpacks 自動偵測並建置 Python 專案,無需 Dockerfile,但如果你偏好明確控制,也支援 Dockerfile。
我可以重複使用 Render 部署的同一個 main.py 嗎?
可以 — 由於兩個平台都遵循相同的 $PORT 慣例,相同的進入點通常可以在兩者之間無需修改即可運作。
我在 Railway 上需要 staypresent.cron() 嗎?
只有在你的特定方案/設定會受到基於閒置的休眠影響時才需要 — 在決定之前,請先查閱 Railway 目前關於你方案的文件。
結論
一個 railway python bot 保持線上的方式與任何現代 PaaS 上的 bot 相同:綁定指定的連接埠、公開專用的健康端點,並讓 StayPresent 監督 bot 程序本身。這個設定與 Railway、Render、Koyeb 和 Heroku 幾乎相同,這正是讓 StayPresent 成為一次性投資,而非每個平台都要重複撰寫樣板的關鍵。
pip install staypresent[prod]
Enter fullscreen mode Exit fullscreen mode
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.