从Glitch迁移至RedHat Openshift后discord.js音乐命令失效
解决Discord机器人迁移到RedHat Openshift后FFMPEG not found的问题
你遇到的这个未处理Promise拒绝错误,核心原因很明确:Glitch的托管环境默认预装了FFmpeg多媒体处理工具,但RedHat Openshift使用的Node.js基础容器镜像是极简配置,并没有包含FFmpeg——而你的音乐命令依赖ytdl-core/discord.js调用FFmpeg来处理音频流,所以迁移后就找不到这个工具了。
下面是几种可行的解决方案,按推荐程度排序:
方案1:自定义Dockerfile安装FFmpeg(最稳定)
Openshift支持通过Dockerfile自定义镜像,你可以基于官方Node.js镜像,手动添加FFmpeg的安装步骤。创建一个名为Dockerfile的文件,内容如下:
# 选择合适的Node.js版本,比如18-alpine(轻量) FROM node:18-alpine # 安装FFmpeg(Alpine系统用apk包管理器,Debian/Ubuntu镜像则用apt-get) RUN apk add --no-cache ffmpeg # 设置容器内的工作目录 WORKDIR /app # 复制package文件到容器,优先安装依赖(利用Docker缓存) COPY package*.json ./ RUN npm install # 复制项目所有代码到容器 COPY . . # 启动机器人的命令 CMD ["node", "index.js"]
把这个Dockerfile和你的项目代码一起推送到代码仓库,然后在Openshift中配置从这个仓库构建镜像并部署——这样你的容器环境就会自带FFmpeg了。
方案2:用S2I构建钩子安装FFmpeg(无需Dockerfile)
如果你不想写Dockerfile,Openshift的S2I(Source-to-Image)构建支持自定义钩子脚本。你可以创建一个构建脚本,在依赖安装前先安装FFmpeg:
- 在项目根目录创建
.s2i/bin/assemble文件,内容如下:
#!/bin/bash # 判断容器系统类型,安装FFmpeg if [ -f /etc/alpine-release ]; then # Alpine系统 apk add --no-cache ffmpeg else # Debian/Ubuntu系统 apt-get update && apt-get install -y ffmpeg && rm -rf /var/lib/apt/lists/* fi # 执行Openshift默认的S2I构建步骤 /usr/libexec/s2i/assemble
- 给脚本添加执行权限:
chmod +x .s2i/bin/assemble
- 把修改后的代码推送到仓库,Openshift在构建时会自动运行这个脚本,先安装FFmpeg再处理你的项目依赖。
补充:代码层面的错误处理
除了环境配置,你还应该在代码中添加Promise拒绝的处理逻辑,避免因为报错导致机器人崩溃。比如在你的play命令里:
if (command.startsWith("play")) { let song = command.substr(4); try { // 你的play命令逻辑:查找歌曲、连接语音频道、播放流等 const connection = await message.member.voice.channel.join(); const stream = ytdl(song, { filter: 'audioonly' }); const dispatcher = connection.play(stream) .on('error', (error) => { console.error('播放错误:', error); message.reply(`播放失败:${error.message}`); }); } catch (error) { console.error('命令执行出错:', error); message.reply('执行播放命令时出错,请检查环境配置!'); } }
这样即使后续还有其他问题,也能明确报错信息,方便排查。
内容的提问来源于stack exchange,提问作者LittleWhole




