Skip to content

Update container image generation to build for ARM using direct method #4280

Open

Description

Image for: Description

Summary of past events

Image for: Summary of past events

ejabberd 22.05 introduced the ejabberd container image, generated in Github Actions with variants for amd64... and arm64 thanks to QEMU.

Unfortunately, QEMU + arm64 + Erlang/OTP 25/26/27 crashes with segmentation fault. The temporary workaround applied since ejabberd 23.04 is to use the binary installers (and Dockerfile uses METHOD=package), as detailed in #3983.

QEMU is fixed!

Image for: QEMU is fixed!

Good news: the original problem is solved in QEMU 8.1.0, so we can revert that temporary workaround and use a newer QEMU to build the container images from source directly again.

This patch contains:

  • Use QEMU 8.1.5 which includes the fix for arm64 crash
    The QEMU issue is
      https://gitlab.com/qemu-project/qemu/-/issues/1034
    The fix commit is
      https://gitlab.com/qemu-project/qemu/-/commit/9719f125b803f4e0fda834cd74a60dfa4ca398e2
    which was first included in QEMU 8.1.0, so 8.1.5 should be good
  • Update Erlang to 27.0 and Elixir to 1.17.3 to fix arm compilation
    Erlang 27.1 is not yet available in https://hub.docker.com/_/erlang

    Compiling with Erlang 26.2 crashes with:
      ==> eex (compile)
      =ERROR REPORT==== 20-Sep-2024::11:58:41.754278 ===
      Error in process <0.115.0> with exit value:
      {function_clause,
        [{'Elixir.Module.Types','-warnings/5-inlined-1-',
             [{column,8}],
             [{file,"lib/module/types.ex"},{line,13}]},
         {'Elixir.Enum',flat_map_list,2,[{file,"lib/enum.ex"},{line,4353}]},
         {'Elixir.Module.ParallelChecker',check_module,3,
             [{file,"lib/module/parallel_checker.ex"},{line,264}]},
         {'Elixir.Module.ParallelChecker','-spawn/4-fun-0-',6,
             [{file,"lib/module/parallel_checker.ex"},{line,82}]}]}
  • TODO: Remove in Dockerfile the METHOD=package and all associated lines, as they would be unnecessary
diff --git a/.github/container/Dockerfile b/.github/container/Dockerfile
index f9a97e0af..e592d6e7d 100644
--- a/.github/container/Dockerfile
+++ b/.github/container/Dockerfile
@@ -1,7 +1,7 @@
 #' Define default build variables
 ## specifc ARGs for METHOD='direct'
-ARG OTP_VSN='26.2'
-ARG ELIXIR_VSN='1.16.2'
+ARG OTP_VSN='27.0'
+ARG ELIXIR_VSN='1.17.3'
 ## specifc ARGs for METHOD='package'
 ARG ALPINE_VSN='3.19'
 ## general ARGs
diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml
index 33ae16960..53e7d204c 100644
--- a/.github/workflows/container.yml
+++ b/.github/workflows/container.yml
@@ -1,8 +1,6 @@
 name: Container
 
 on:
-  schedule:
-    - cron: '22 2 */6 * *' # every 6 days to avoid gha cache being evicted
   push:
     paths-ignore:
     - '.devcontainer/**'
@@ -28,52 +26,6 @@ jobs:
         with:
           fetch-depth: 0
 
-      - name: Cache build directory
-        uses: actions/cache@v4
-        with:
-          path: ~/build/
-          key: ${{runner.os}}-ctr-ct-ng-1.26.0
-
-      - name: Get erlang/OTP version for bootstrapping
-        run: |
-          echo "OTP_VSN=$(awk '/^otp_vsn=/ {{gsub(/[^0-9.rc-]/, ""); print}}' tools/make-binaries)" >> $GITHUB_ENV
-          echo "ELIXIR_VSN=$(awk '/^elixir_vsn=/ {{gsub(/[^0-9.]/, ""); print}}' tools/make-binaries)" >> $GITHUB_ENV
-
-      - name: Install prerequisites
-        run: |
-          sudo apt-get -qq update
-          sudo apt-get -qq install makeself
-          # https://github.com/crosstool-ng/crosstool-ng/blob/master/testing/docker/ubuntu21.10/Dockerfile
-          sudo apt-get -qq install build-essential autoconf bison flex gawk
-          sudo apt-get -qq install help2man libncurses5-dev libtool libtool-bin
-          sudo apt-get -qq install python3-dev texinfo unzip
-
-      - name: Install erlang/OTP
-        uses: erlef/setup-beam@v1
-        with:
-          otp-version: ${{ env.OTP_VSN }}
-          elixir-version: ${{ env.ELIXIR_VSN }}
-          version-type: strict
-
-      - name: Remove Elixir Matchers
-        run: |
-          echo "::remove-matcher owner=elixir-mixCompileWarning::"
-          echo "::remove-matcher owner=elixir-credoOutputDefault::"
-          echo "::remove-matcher owner=elixir-mixCompileError::"
-          echo "::remove-matcher owner=elixir-mixTestFailure::"
-          echo "::remove-matcher owner=elixir-dialyzerOutputDefault::"
-
-      - name: Build musl-libc based binary archives
-        run: |
-          sed -i "s|targets='.*'|targets='x86_64-linux-musl aarch64-linux-musl'|" tools/make-binaries
-          mv .github/container/ejabberdctl.template .
-          CHECK_DEPS=false tools/make-binaries
-
-      - name: Collect packages
-        run: |
-          mkdir tarballs
-          mv ejabberd-*.tar.gz tarballs
-
       - name: Checkout ejabberd-contrib
         uses: actions/checkout@v4
         with:
@@ -103,6 +55,8 @@ jobs:
 
       - name: Set up QEMU
         uses: docker/setup-qemu-action@v3
+        with:
+          image: tonistiigi/binfmt:qemu-v8.1.5
 
       - name: Set up Docker Buildx
         uses: docker/setup-buildx-action@v3
@@ -111,7 +65,6 @@ jobs:
         uses: docker/build-push-action@v6
         with:
           build-args: |
-            METHOD=package
             VERSION=${{ steps.gitdescribe.outputs.ver }}
           cache-from: type=gha
           cache-to: type=gha,mode=max

ARM runner!

Image for: ARM runner!

Even better news:

We expect to begin offering Arm runners for open source projects by the end of the year.

That would allow us to generate arm64 container images without using QEMU at all: faster image generation and smaller build scripts (Dockerfile and container.yml).

Proposal

Image for: Proposal

Maybe, instead of switching now to QEMU 8.1.0 and build image directly from source, we can wait a few months and jump directly to the definitive solution: build ARM image using ARM-based runner.

And once that simplification is done, #4261 can be updated and finally applied.

Metadata

Image for: Metadata

Metadata

Image for: Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    Image for: Issue actions