Python Discord Bot部署至Google Cloud Run报Container failed to start错误
问题根因
Cloud Run的默认运行规则要求容器必须在PORT环境变量指定的端口上监听HTTP请求,平台会持续通过健康检查探测该端口,探测失败就会判定容器启动异常并终止实例。你的Discord Bot是基于WebSocket长连接运行的常驻进程,全程没有启动HTTP服务监听指定端口,因此哪怕Bot已经成功登录Discord,依然会被Cloud Run判定为启动失败而销毁。
解决方案(二选一即可)
方案1:新增轻量HTTP服务满足检测要求(改动最小)
- 先在
requirements.txt中添加aiohttp依赖:
aiohttp>=3.8.0
- 修改
discord_bot.py代码,同时启动HTTP健康检查服务和Discord Bot:
import os import asyncio import discord from aiohttp import web TOKEN = os.environ['DISCORD_BOT_LEVEL_TOKEN'] PORT = int(os.environ.get('PORT', 8080)) client = discord.Client() # 新增健康检查接口 async def health_check(request): return web.Response(text="OK") # 启动HTTP服务 async def run_http_server(): app = web.Application() app.add_routes([web.get('/health', health_check), web.get('/', health_check)]) runner = web.AppRunner(app) await runner.setup() site = web.TCPSite(runner, '0.0.0.0', PORT) await site.start() @client.event async def on_ready(): print('We have successfully logged in as {0.user}'.format(client)) @client.event async def on_message(message): if message.author == client.user: return if message.content.lower() == 'hello': await message.channel.send(f'Hello, {message.author.display_name}!') return if message.content.lower() == 'bye': await message.channel.send(f'See you later, {message.author.display_name}!') return # 同时启动两个异步任务 async def main(): await asyncio.gather( run_http_server(), client.start(TOKEN) ) if __name__ == "__main__": asyncio.run(main())
方案2:调整Cloud Run配置适配非HTTP服务
不需要修改代码,在Cloud Run部署页面调整配置:
- 健康检查配置:将启动探测、存活探测的检查类型从「HTTP」改为「TCP」,端口指定为8080
- 容器启动命令无需改动,平台会直接检测端口是否被占用即可通过检查
额外必选配置
无论选哪种方案,都需要调整Cloud Run的运行配置,否则Bot会频繁断线:
- CPU分配规则修改为「始终处于分配状态」,不要使用默认的「仅在处理请求期间分配」,否则没有HTTP请求时实例CPU会被冻结,导致Discord的WebSocket连接断开
- 将请求超时时间调整到最大值(目前支持最高86400秒),避免实例被平台自动回收
内容的提问来源于stack exchange,提问作者mtbell
相关产品推荐
相关产品推荐

