Skip to content

ci: build a multi-arch main image #11668

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
66 changes: 44 additions & 22 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ permissions:
checks: none
contents: read
deployments: none
id-token: write
issues: none
packages: write
pull-requests: none
Expand Down Expand Up @@ -655,12 +656,10 @@ jobs:
# to main branch. We are only building this for amd64 platform. (>95% pulls
# are for amd64)
needs: changes
if: github.ref == 'refs/heads/main' && needs.changes.outputs.docs-only == 'false'
if: needs.changes.outputs.docs-only == 'false'
runs-on: ${{ github.repository_owner == 'coder' && 'buildjet-8vcpu-ubuntu-2204' || 'ubuntu-latest' }}
env:
DOCKER_CLI_EXPERIMENTAL: "enabled"
outputs:
IMAGE: ghcr.io/coder/coder-preview:${{ steps.build-docker.outputs.tag }}
IMAGE: ghcr.io/coder/coder-preview:${{ steps.build.outputs.tag }}
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -687,39 +686,62 @@ jobs:
run: sudo apt-get install -y zstd

- name: Build
id: build
run: |
set -euxo pipefail
go mod download

version="$(./scripts/version.sh)"
make gen/mark-fresh
make -j \
build/coder_linux_amd64 \
build/coder_linux_{amd64,arm64,armv7} \
build/coder_"$version"_windows_amd64.zip \
build/coder_"$version"_linux_amd64.{tar.gz,deb}

# create base image tag
base_tag="coder-base:$version"

- name: Build and Push Linux amd64 Docker Image
id: build-docker
run: |
set -euxo pipefail
version="$(./scripts/version.sh)"
tag="main-$(echo "$version" | sed 's/+/-/g')"
# replace + with - in tag
base_tag="${base_tag/+/-}"

export CODER_IMAGE_BUILD_BASE_TAG="$(CODER_IMAGE_BASE=coder-base ./scripts/image_tag.sh --version "$version")"
./scripts/build_docker.sh \
--arch amd64 \
--target "ghcr.io/coder/coder-preview:$tag" \
--version $version \
--push \
build/coder_linux_amd64
# create image tag
tag="main-$version"

# Tag as main
docker tag "ghcr.io/coder/coder-preview:$tag" ghcr.io/coder/coder-preview:main
docker push ghcr.io/coder/coder-preview:main
# replace + with - in tag
tag="${tag/+/-}"

# Store the tag in an output variable so we can use it in other jobs
# create an empty build context directory
mkdir -p build-context

# copy the build artifacts to the build context
cp build/coder_linux_* build-context/
# We use TARGETARCH to determine the architecture of the binary
# in the Dockerfile. This is arm for armv7.
mv build-context/coder_linux_armv7 build-context/coder_linux_arm

# export version, and tag as outputs
echo "version=$version" >> $GITHUB_OUTPUT
echo "tag=$tag" >> $GITHUB_OUTPUT

- name: Set up Depot
uses: depot/setup-action@v1

- name: Build and push multi arch image
uses: depot/build-push-action@v1
with:
project: 9rcqzb56rm
context: ./build-context
platforms: linux/amd64,linux/arm64,linux/arm/v7
file: ./scripts/Dockerfile.multiarch
push: ${{ github.event_name != 'pull_request' }}
tags: |
ghcr.io/coder/coder-preview:${{ steps.build.outputs.tag }}
ghcr.io/coder/coder-preview:main
ghcr.io/coder/coder-preview:latest
build-args: |
BASE_IMAGE=ghcr.io/coder/coder-base
CODER_VERSION=${{ steps.build.outputs.version }}

- name: Prune old images
uses: vlaurin/action-ghcr-prune@v0.5.0
with:
Expand Down
21 changes: 21 additions & 0 deletions scripts/Dockerfile.multiarch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This is the multi-arch Dockerfile used for Coder. All binaries are built
# using the go toolchain on the host and then copied into the build context.
ARG BASE_IMAGE
FROM $BASE_IMAGE

# LABEL doesn't add any real layers so it's fine (and easier) to do it here than
# in the build script.
ARG CODER_VERSION
LABEL \
org.opencontainers.image.title="Coder" \
org.opencontainers.image.description="A tool for provisioning self-hosted development environments with Terraform." \
org.opencontainers.image.url="https://github.com/coder/coder" \
org.opencontainers.image.source="https://github.com/coder/coder" \
org.opencontainers.image.version="$CODER_VERSION"


# The coder binary is available in the build context.
ARG TARGETARCH
COPY --chown=1000:1000 --chmod=755 coder_linux_${TARGETARCH} /opt/coder

ENTRYPOINT [ "/opt/coder", "server" ]