Cloud Native 7 min read

How to Build Multi-Arch Go Images with Jenkins and Buildah

This guide explains how to use Jenkins together with Buildah to automatically build and push multi‑architecture (amd64 and arm64) container images for Go applications, covering prerequisites, a complete Jenkinsfile, tips for faster builds, and a test pipeline demonstration.

Linux Ops Smart Journey
Linux Ops Smart Journey
Linux Ops Smart Journey
How to Build Multi-Arch Go Images with Jenkins and Buildah

In the rapidly evolving cloud‑native ecosystem, container images are no longer limited to the traditional x86_64 architecture. With the proliferation of ARM devices, building multi‑arch images has become a standard requirement in CI/CD pipelines.

While Docker + Buildx has been the common solution, Docker is not optimal in all environments, especially in Kubernetes or OpenShift, where Buildah offers a lighter, more secure alternative.

Prerequisites

Access to a Kubernetes cluster (see referenced article)

Jenkins service available (see referenced article)

Familiarity with Buildah

Understanding of Go compilation

Jenkinsfile

podTemplate(label: BUILD_TAG, inheritFrom: "default", imagePullSecrets: ["harbor-user-secret"], envVars: [
  envVar(key: "http_proxy", value: "http://172.139.20.170:3888"),
  envVar(key: "https_proxy", value: "http://172.139.20.170:3888"),
  envVar(key: "no_proxy", value: "localhost,*.cluster.local,*.svc,172.139.20.0/24,10.96.0.0/16,10.244.0.0/16")
], containers: [
  containerTemplate(name: 'golang', image: 'core.jiaxzeng.com/jiaxzeng/golang:1.23.12-alpine', command: 'cat', ttyEnabled: true)
], yaml: '''
  kind: Pod
  spec:
    containers:
    - name: build
      image: core.jiaxzeng.com/library/buildah:v1.40.1
      command: ["cat"]
      tty: true
      securityContext:
        privileged: true
      env:
      - name: http_proxy
        value: http://172.139.20.170:3888
      - name: https_proxy
        value: http://172.139.20.170:3888
      - name: no_proxy
        value: localhost,*.cluster.local,*.svc,172.139.20.0/24,10.96.0.0/16,10.244.0.0/16
''' ) {
  node(BUILD_TAG) {
    properties([
      parameters([
        string(name: 'Brance', defaultValue: 'master', description: '请输入构建项目的分支名称')
      ])
    ])
    stage('拉取代码') {
      sh 'git config --global http.sslverify false; git config --global https.sslverify false'
      git branch: "${Brance}", credentialsId: 'gitlab-auth', url: 'https://gitlab.jiaxzeng.com/jiaxzeng/simple.git'
    }
    stage('代码测试') {
      echo "代码测试"
    }
    stage('编译代码') {
      container('golang'){
        sh '''
          go env -w GOPROXY=https://goproxy.cn,direct
          rm go.mod  go.sum
          go mod init simple
          go mod tidy 
          GOOS=linux GOARCH=amd64 go build -o out/amd64/simple .
          GOOS=linux GOARCH=arm64 go build -o out/arm64/simple .
        '''
      }
    }
    stage('打包镜像') {
      parallel (
        "amd64架构": {
          container('build'){
            withCredentials([usernamePassword(credentialsId: 'harbor-auth', passwordVariable: 'password', usernameVariable: 'username')]) {
              sh '''
                echo ${password} | buildah login --tls-verify=false core.jiaxzeng.com -u ${username} --password-stdin
                sed -ri 's@(COPY --from=Build|COPY out).*@COPY out/amd64/simple /usr/local/bin/@g' Dockerfile 
                cat Dockerfile
                buildah build --tls-verify=false --jobs=$(nproc) --platform=linux/amd64 -t simle:${Brance}-amd64 .
              '''
            }
          }
        },
        "arm64架构": {
          container('build'){
            withCredentials([usernamePassword(credentialsId: 'harbor-auth', passwordVariable: 'password', usernameVariable: 'username')]) {
              sh '''
                echo ${password} | buildah login --tls-verify=false core.jiaxzeng.com -u ${username} --password-stdin
                sed -ri 's@(COPY --from=Build|COPY out).*@COPY out/arm64/simple /usr/local/bin/@g' Dockerfile 
                cat Dockerfile
                buildah build --tls-verify=false --jobs=$(nproc) --platform=linux/arm64 -t simle:${Brance}-arm64 .
              '''
            }
          }
        }
      )
    }
    stage('推送多架构镜像') {
      container('build'){
        sh '''
          buildah manifest create --all core.jiaxzeng.com/jiaxzeng/simple:${Brance} simle:${Brance}-amd64 simle:${Brance}-arm64
          buildah manifest push --tls-verify=false core.jiaxzeng.com/jiaxzeng/simple:${Brance} --all "docker://core.jiaxzeng.com/jiaxzeng/simple:${Brance}"
        '''
      }
    }
  }
}

Tip

Buildah uses multi‑stage builds; Go compilation can be very slow, so compiling first and then copying the binary into the image speeds up the process considerably.

Test Pipeline

1. Click “Build with Parameters” and provide the corresponding version number.

Conclusion

In the pursuit of a lightweight, secure, and portable CI/CD architecture, Buildah is becoming a powerful alternative to Docker. By integrating Jenkins with Buildah, we achieve automated multi‑arch image builds for Go programs while avoiding the security risks associated with the Docker daemon.

CI/CDGoJenkinsBuildahContainer ImagesMulti-Arch
Linux Ops Smart Journey
Written by

Linux Ops Smart Journey

The operations journey never stops—pursuing excellence endlessly.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.