I needed to get a docker image created and available publicly . I decided to experiment by using the Sourcehut build system and Github's container registry to publish the image whenever changes are commited to the repo.
A mechanism for creating and publishing my image from the shell was already
complete. I use just as make
analog for
this sort of thing, and my hope was to use this approach with Sourcehut.
Table of Contents #
Platform Info #
ghcr.io #
Here is the reference doc for ghcr.io. It boils down to:
- Creating a personal access token (PAT) with permissions sufficient to publish images.
- Using that personal access token and the
docker
command to login and publish the image. - Remembering that the first time a package is published, its visibility will be private.
Sourcehut Builds #
The user manual is short and sweet. Using a
YAML file called .build.yml
, the information required to configure the build
agent (like base image, list of packages, source files, secrets) is supplied.
Tasks for the build are Bash scripts. I'll need to:
- Install & configure build dependencies.
- Run the build.
- Use the secret GitHub PAT to publish the image.
Step by Step #
Create the GH personal access token #
A personal access token with scopes=write:packages needs to be created. There is a UI bug which prevents minimal permssions like this from being selected (as documented in the container registry reference doc.
Use this link https://github.com/settings/tokens/new?scopes=write:packages to create a personal access token with the minimal permissions.
Create a Sourcehut secret #
Sourcehut secrets are managed at https://builds.sr.ht/secrets. Unlike some
other build systems which expose secrets as environment variables, Sourcehut
presents secrets to build agents as files. I configured this secret to reside
in the file ~/.envdir/GH_PAT
.
![[Pasted image 20230227161442.png]]
Create the build manifest #
Here is my build manifest, .build.yml
, which should be created at the root of
the git repository.
1image: alpine/edge
2
3secrets:
4 - 0ee986ff-5686-43cd-ac3a-1fe5b2e5dd8f
5
6sources:
7 - https://git.sr.ht/~jswank/alpine-cli
8
9packages:
10 - podman # required to buuld / publish image
11 - just # the task runner
12 - runit # includes chpst for env var handling
13
14tasks:
15 # cgroups need to be running in order to run podman
16 - prep: |
17 sudo rc-service cgroups start
18 sleep 1
19
20 # build the image using the just recipe
21 # - sudo (-u root) is required to run podman without more setup
22 - build: |
23 cd alpine-cli
24 sudo just build
25
26 # publish the image using the just recipe
27 # - set environment variables from the ~/.envdir directory. see
28 # http://smarden.org/runit/chpst.8.html for details on chpst
29 # - sudo (-u root) is required to run podman without more setup
30 # - sudo --preserve-env is required to pass environment variables
31 - publish: |
32 cd alpine-cli
33 chpst -e ~/.envdir \
34 sudo --preserve-env \
35 just registry_pass_var=GH_PAT publish
My build process uses podman to create and publish the container: in addition to installing that package on the build agent, some setup needs to happen to make it work. I did the minimal amount of setup - and did not configure the build agent to support non-root podman usage. I.e. the build and publish steps need to run as root.
The build task executes the just recipe build. It is invoked by sudo so that podman will function.
The publish task executes the just recipe publish. An environment variable
$GH_PAT
needs to be set - the venerable
chpst command is used to accomplish
this by making use of the secret written to ~/.envdir/GH_PAT
.
Perform the build #
When content is pushed to a Sourcehut repo containing a .build.yml, a build will occur. There are alternative ways to trigger a build that do not require a push - for instance, a manifest can be submitted via the ui or via the API.
Make the image publicly available #
After some trial and error, my image was published to ghcr.io - but was not available publicly. I went to https://github.com/users/jswank/packages/container/alpine-cli/ and updated the settings to make the package visible.
More Info #
-
This article refers to the image built at https://git.sr.ht/~jswank/alpine-cli. Of interest may be the build manifest. and the justfile.
-
It's convenient to trigger builds without pushing to a git repo. The easiest way to trigger a build is to use the Sourcehut
hut
command available at https://sr.ht/~emersion/hut/. I have also used a more limited shell script.