为Heroku编译C++可执行文件遇阻,求解决方案
我在Heroku上部署了一个Node.js服务器,现在为其添加了一个作为子进程运行的C++函数。该程序在本地Ubuntu和macOS机器上运行正常,此前确认dyno架构为x86_64,因此安装Ubuntu 16.04虚拟机进行编译,但部署后仍出现可执行文件无法运行的错误。经排查发现dyno的操作系统已变更,虚拟机编译方式不实用。论坛上5年前的相关方案均无法生效,需要可行解决办法。
Heroku日志错误信息:
2023-03-24T12:32:33.665970+00:00 heroku[router]: at=error code=H13 desc="Connection closed without response" method=GET path="/path/ofRouteThatRunsChildProcess" host=myaddress request_id=2a9a4b4d-c073-415d-9af2-600ee2728a6b fwd="91.17.39.75" dyno=web.1 connect=0ms service=55ms status=503 bytes=0 protocol=https
2023-03-24T12:32:33.797308+00:00 heroku[web.1]: Process exited with status 1
1. 使用Heroku官方C++ buildpack在部署时编译代码
Heroku支持多buildpack,先添加Node.js buildpack,再添加C++ buildpack,让Heroku在部署过程中直接编译你的C++代码,确保编译环境和dyno运行环境一致:
- 在项目根目录执行以下命令添加buildpack:
heroku buildpacks:add heroku/nodejs heroku buildpacks:add heroku/cpp - 确保项目根目录有
Makefile或者CMakeLists.txt,Heroku的C++ buildpack会自动执行编译流程,生成适配当前dyno环境的可执行文件。
2. 检查C++代码的依赖项
可执行文件无法运行大概率是依赖缺失,即使架构匹配,dyno的系统库版本可能和本地或旧虚拟机不一致:
- 用
ldd命令在本地编译后的可执行文件上查看依赖,对比Heroku dyno上的库版本:# 在本地执行 ldd your_executable - 如果有非系统默认的依赖,需要将依赖库和可执行文件一起打包,或者通过buildpack安装这些依赖。比如用
apt安装依赖,可以在项目根目录创建Aptfile,写入需要安装的包名,然后添加heroku-community/aptbuildpack:heroku buildpacks:add heroku-community/apt
3. 改用Docker容器部署
如果buildpack方式仍有问题,直接用Docker打包整个环境,确保运行环境完全可控:
- 编写
Dockerfile,基于Heroku支持的基础镜像(比如heroku/nodejs),在容器内编译C++代码并安装所有依赖:FROM heroku/nodejs:20 WORKDIR /app COPY . . # 安装C++编译工具和依赖 RUN apt-get update && apt-get install -y build-essential cmake # 编译C++代码 RUN make # 设置Node.js启动命令 CMD ["node", "server.js"] - 启用Heroku的容器部署:
heroku container:login heroku container:push web heroku container:release web
4. 调试可执行文件的运行错误
如果以上方法仍未解决,直接在Heroku dyno上调试可执行文件:
- 进入dyno的bash终端:
heroku run bash - 手动运行C++可执行文件,查看具体错误信息:
./your_executable - 常见错误包括权限问题(确保可执行文件有执行权限,编译后设置
chmod +x your_executable)、库路径问题(设置LD_LIBRARY_PATH)等。
内容的提问来源于stack exchange,提问作者DoMaxBa

