You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Heroku上同时运行Flask与Discord Bot?

解决Heroku上同时运行Flask和Discord Bot的问题

问题根源

  • 用gunicorn app:app时,仅启动Flask服务,Discord Bot的代码未被执行
  • 用python main.py时,Flask的app.run()未绑定Heroku分配的PORT环境变量,导致Web服务无法被Heroku检测到;同时Heroku的web进程要求服务必须监听指定端口,否则会判定启动失败

解决方案

1. 修改app.py,适配Heroku端口并整合Bot启动

更新app.py,让它读取Heroku的端口变量,同时在Flask启动时启动Discord Bot:

from flask import Flask
import threading
import asyncio
import mybot
import os

app = Flask(__name__)

@app.route('/')
def index():
    return 'hello world'

def run_bot():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    # 从环境变量读取机器人令牌
    loop.create_task(mybot.bot.start(os.getenv('BOT_TOKEN')))
    loop.run_forever()

def run_server():
    # 读取Heroku分配的端口,本地测试默认用5000
    port = int(os.getenv('PORT', 5000))
    # 绑定0.0.0.0允许外部访问
    app.run(host='0.0.0.0', port=port)

def run_async():
    # 启动Bot守护线程
    bot_thread = threading.Thread(target=run_bot)
    bot_thread.daemon = True
    bot_thread.start()
    # 启动Flask服务
    run_server()

# 直接运行app.py时启动整合服务
if __name__ == '__main__':
    run_async()

2. 修改mybot.py,从环境变量读取敏感配置

避免硬编码服务器ID,改用环境变量存储:

import discord
from discord.ext import commands
from discord import app_commands
import os

class Bot(commands.Bot):
    def __init__(self):
        intents = discord.Intents.all()
        super().__init__(command_prefix = "!",
                         intents = intents,
                         help_command=None
                         )
    
    async def setup_hook(self) -> None:
        # 从环境变量读取服务器ID
        guild_id = int(os.getenv('GUILD_ID'))
        await self.tree.sync(guild = discord.Object(id = guild_id))
        print(f"Now login user: {self.user}.")
bot = Bot()

@bot.hybrid_command(name = "ping", with_app_command = True, description = "pong")
@app_commands.guilds(discord.Object(id = int(os.getenv('GUILD_ID'))))
async def ping(ctx: commands.Context):
    await ctx.defer(ephemeral = True)
    await ctx.reply("pong!")

3. 更新Procfile

让gunicorn启动Flask服务,同时触发Bot的启动逻辑:

web: gunicorn --workers=1 app:app

注:指定--workers=1是为了避免启动多个Bot实例,造成资源浪费和重复登录

4. 配置Heroku环境变量

在Heroku应用的「设置」页面,添加以下环境变量:

  • BOT_TOKEN: 你的Discord机器人令牌
  • GUILD_ID: 你的服务器数字ID

原理说明

  • Flask启动时会调用run_async(),启动一个守护线程运行Discord Bot的异步事件循环
  • Flask服务绑定到Heroku指定的端口,满足web进程的运行要求
  • 敏感配置从环境变量读取,符合Heroku的安全实践,也方便不同环境切换

内容的提问来源于stack exchange,提问作者SunnyShoun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 21:13:26