Apple M1/M2构建GraalVM Native适配arm64及Heroku部署咨询
问题解答
1. Apple M1/M2构建GraalVM Native二进制能否在arm64 Ubuntu运行?
直接在M1/M2 macOS上编译出的原生二进制是macOS arm64格式,没法直接在Ubuntu arm64(Linux arm64)上跑——两者的操作系统ABI、系统库依赖完全不同。但可以通过两种方式实现跨平台构建:
- 容器化构建:在M1/M2上用Docker启动Linux arm64容器,在容器内完成GraalVM Native编译,生成的二进制直接兼容Ubuntu arm64。Quarkus的
-Dquarkus.native.container-build=true参数就是干这个的,会自动拉起容器完成编译。 - 交叉编译:用GraalVM的
--target指定linux-aarch64目标,同时要安装Linux arm64的交叉编译工具链(比如gcc-aarch64-linux-gnu)。不过这种方式配置繁琐,容器化是更省心的选择。
2. M2 Mac构建Quarkus镜像部署Heroku的可行性与实现方法
完全可行,Heroku已经支持arm64架构的容器镜像。你有两种实现路径:
方案一:本地M2 Mac直接构建并推送镜像
- 确保Docker Desktop在M2上已开启Rosetta 2(或直接支持Linux arm64镜像,M1/M2默认支持)。
- 用Quarkus命令生成Linux arm64镜像:
这个命令会先在容器内编译出Linux arm64的原生二进制,再打包成Docker镜像。mvn package -Pnative -Dquarkus.native.container-build=true -Dquarkus.container-image.build=true - 登录Heroku容器注册表:
heroku container:login - 标记并推送镜像到Heroku:
heroku container:push web -a <你的Heroku应用名> heroku container:release web -a <你的Heroku应用名>
方案二:优化现有GitHub Action流程(更适合CI/CD)
你当前的Action已经在Ubuntu环境构建,可优化确保稳定生成Linux arm64二进制:
- 明确指定运行器架构为arm64,避免x86_64环境干扰:
name: Heroku-Bot-CI Build artifacts for new tag on: push: tags: - '[0-9].[0-9].[0-9]' jobs: build_and_upload: name: Build Linux arm64 Native Binary runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: graalvm/setup-graalvm@v1 with: java-version: 21 distribution: 'graalvm' architecture: 'aarch64' # 指定arm64架构 - run: mvn package -Pnative -Dquarkus.native.container-build=false # 直接在Ubuntu arm64环境编译,无需容器 - uses: actions/upload-artifact@v4 with: name: heroku-bot-runner-${{github.ref_name}} path: target/heroku-bot-1.0-SNAPSHOT-runner if-no-files-found: error - 还可以在Action中直接构建Docker镜像并推送到Heroku,省去手动上传artifact的步骤:
添加以下步骤到jobs里:
记得在GitHub仓库的Secrets中配置- name: Login to Heroku Container Registry env: HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }} run: heroku container:login - name: Build and push Docker image env: HEROKU_APP_NAME: ${{ secrets.HEROKU_APP_NAME }} run: | docker build -t registry.heroku.com/$HEROKU_APP_NAME/web . docker push registry.heroku.com/$HEROKU_APP_NAME/web - name: Release to Heroku env: HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }} HEROKU_APP_NAME: ${{ secrets.HEROKU_APP_NAME }} run: heroku container:release web -a $HEROKU_APP_NAMEHEROKU_API_KEY和HEROKU_APP_NAME。
内容的提问来源于stack exchange,提问作者tostao
相关产品推荐
相关产品推荐

