使用 StayPresent 部署一个永不休眠的 Railway Python 机器人——端口绑定、健康检查、自 ping 以及崩溃恢复。
在 Railway 上使用 StayPresent 运行永不休眠的 Python 机器人
Railway 会自动检测 Python 项目并在几分钟内完成部署,但铁路 Python 机器人(Discord 机器人、Telegram 机器人或爬虫)仍会遇到每个 PaaS 都存在的核心问题:平台期望一个面向 HTTP 的进程,而机器人的事件循环或网关连接并不会自然地提供这样的进程。本指南介绍如何使用 StayPresent 将机器人部署到 Railway 并保持在线。
目录
- Railway 如何检测并运行 Python 应用
$PORT要求- 设置 StayPresent
- Railway 仪表盘中的健康检查
- 针对不活动敏感方案的自 Ping
- 崩溃恢复
- 完整可运行示例
- 最佳实践
- 常见错误
- 常见问题
- 结论
Railway 如何检测并运行 Python 应用
Railway 会通过 Nixpacks 从 requirements.txt(或 pyproject.toml)自动检测 Python 项目并为其构建容器,无需 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
如果你的机器人根本没有绑定到这个端口——这对于 Discord 或 Telegram 机器人来说是正常、预期的行为——即使你的机器人本身可能运行良好,Railway 的健康检查(如果已启用)也会报告部署不健康。
设置 StayPresent
安装生产环境扩展,以便让 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 仍返回 {"status": "ok"},与上述配置无关
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 不会离开机器,对不活动检测没有影响。
崩溃恢复
机器人会因各种常见原因崩溃,而 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 会以机器人原始退出码退出整个进程——让 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 自己的重启策略在容器级别运行;容器仍在运行但其内部的机器人子进程崩溃是 StayPresent 直接处理的另一种失败模式。
常见问题
Railway 是否需要 Dockerfile?
不需要——Railway 可以通过 Nixpacks 自动检测并构建 Python 项目,无需 Dockerfile;当然,如果你希望显式控制,也支持 Dockerfile。
能否复用 Render 部署中的同一个 main.py?
可以——因为两个平台都遵循相同的 $PORT 约定,相同的入口点通常无需修改即可在两者上运行。
在 Railway 上是否需要 staypresent.cron()?
仅当你的具体方案/配置受不活动休眠影响时才需要——在决定前请查阅 Railway 当前的方案文档。
结论
一个铁路 Python 机器人保持在线的方式与在任何现代 PaaS 上运行机器人相同:绑定到分配的端口、暴露专用的健康端点,并让 StayPresent 监督机器人进程本身。该设置在 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.