Skip to content

Publish UBI as a container image #147

@polarathene

Description

@polarathene

This would be for convenience of using UBI without extra steps to acquire a version that matches the platform and extract it.

A PR was raised for just that implements this post-release by having a simple Dockerfile the official project manages that copies the appropriate GH release artifact. It should be possible to adapt that PR to the ubi repo here.


name: Tests and release
on:
push:
branches:
- "**"
tags-ignore:
- "ubi-*"
pull_request:

- name: Publish artifacts and release
uses: houseabsolute/actions-rust-release@v0
with:
executable-name: ubi
target: ${{ matrix.platform.target }}
action-gh-release-parameters: '{ "make_latest": false }'
if: matrix.toolchain == 'stable' && matrix.platform.features == ''

That last step calls out to your own maintained release action that at the end publishes to GH Releases if the conditions such as a release tag are met.

After that action is done publishing a new release with the UBI binaries, a workflow can be triggered via on.release like below.

Reference workflow and Dockerfile

NOTE: I'm a bit busy atm, this example might need a bit more revision but should mostly be viable. I'll open a PR once I have time to spare (hopefully in next day or so).

name: 'Build and Publish the container image'

on:
  release:
    types:
      - published

  # Manual trigger via GH Actions page (runs this workflow from a selected tag or branch),
  # NOTE: Affects the value `github.ref_type` (`branch` or `tag`) + commit cloned for `Dockerfile` source.
  workflow_dispatch:
    inputs:
      # Optional input to override tag
      tag:
        description: 'Release tag of UBI (to include in image + influences image tag)'
        required: false
        type: string

env:
  RELEASE_VERSION: ${{ inputs.tag || github.ref_name }}

jobs:
  container:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Prepare image metadata
        id: metadata
        uses: docker/metadata-action@v5
        env:
          DOCKER_METADATA_ANNOTATIONS_LEVELS: index
        with:
          images: |
            ghcr.io/${{ github.repository }}
          # NOTE: The `semver` tag type below (with the default `flavor.latest=auto` action setting),
          # will implicitly append a `latest` tag to publish:
          # https://github.com/docker/metadata-action/issues/567#issuecomment-3579068205
          # https://github.com/docker/metadata-action/issues/461#issuecomment-2680849083
          tags: |
            type=semver,pattern={{major}}.{{minor}}.{{patch}},value=${{ env.RELEASE_VERSION }}
            type=semver,pattern={{major}}.{{minor}},value=${{ env.RELEASE_VERSION }}
            # NOTE: `enable` condition required until no longer tagging major-zero versions:
            type=semver,pattern={{major}},value=${{ env.RELEASE_VERSION }},enable=${{ !startsWith(github.ref, 'refs/tags/v0.') }}

          # Override defaults from `docker/metadata-action`:
          # https://github.com/docker/metadata-action/issues/585
          annotations:
            org.opencontainers.image.created={{ commit_date 'YYYY-MM-DDTHH:mm:ss.SSS[Z]' }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push container image
        uses: docker/build-push-action@v6
        env:
          SOURCE_DATE_EPOCH: 0
        with:
          provenance: false
          push: true
          platforms: linux/amd64,linux/arm64
          tags: ${{ steps.metadata.outputs.tags }}
          annotations: ${{ steps.metadata.outputs.annotations }}
          outputs: type=image,oci-mediatypes=true,oci-artifact=true,rewrite-timestamp=true
          build-args: |
            RELEASE_TAG=${{ env.RELEASE_VERSION }}

Dockerfile:

# syntax=docker/dockerfile:1

# NOTE: ARGs `BUILDPLATFORM` + `TARGETARCH` are implicitly defined by BuildKit:
# https://docs.docker.com/reference/dockerfile/#automatic-platform-args-in-the-global-scope
# NOTE: BuildKit supplied ARGs use convention amd64 / arm64 (instead of the mixed arch convention used by UBI)
# https://itsfoss.com/arm-aarch64-x86_64
#
# Map arch naming conventions from BuildKit to UBI convention (TARGETARCH => UBI_ARCH):
FROM --platform=${BUILDPLATFORM} alpine AS downloader-amd64
ARG UBI_ARCH=x86_64
FROM --platform=${BUILDPLATFORM} alpine AS downloader-arm64
ARG UBI_ARCH=arm64


# Fetch the expected version of `ubi` via GH Releases:
FROM downloader-${TARGETARCH} AS downloader
SHELL ["/bin/ash", "-eux", "-o", "pipefail", "-c"]
# This ARG will be set via GitHub Actions during release builds
ARG RELEASE_TAG
ARG RELEASE_URL="https://github.com/houseabsolute/ubi/releases/download/${RELEASE_TAG}/ubi-Linux-musl-${UBI_ARCH}.tar.gz"
RUN wget -O - "${RELEASE_URL}" \
    | tar --directory /usr/local/bin --extract --gzip --no-same-owner ubi


FROM scratch
# UBI needs at least `/tmp` to exist when running:
COPY --from=scratch / /tmp
COPY --from=downloader /usr/local/bin/ubi /ubi
ENTRYPOINT ["ubi"]
CMD ["--help"]
# Build it:
docker build --build-arg RELEASE_VERSION=v0.9.0 --tag localhost/ubi:0.9.0 .

# Run it:
docker run --rm -it localhost/ubi:0.9.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions