Welcome to your brand-new Atomic AlmaLinux Respin!
In the "config" action, you'll find a job where you can configure several key variables:
REGISTRY
: The container registry to push your image to (default: GitHub Container Registryghcr.io
).REGISTRY_USER
: Your username for the registry.IMAGE_PATH
: The path/namespace for your image.IMAGE_NAME
: The name of your image.PLATFORMS
: A quoted, comma-separated list of platforms to build for (e.g.,"amd64,arm64"
).
If your registry is not GitHub or you need a specific token, search for REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }}
in the workflow files and replace it with the appropriate secret.
By default, this template uses the base image quay.io/almalinuxorg/atomic-desktop-gnome:10
, maintained by the
AlmaLinux Atomic SIG. If you prefer KDE, you can use
quay.io/almalinuxorg/atomic-desktop-kde:10
instead.
To switch images, change the FROM
line in the Dockerfile. If your image use a different
signing key, download the new Cosign public key and specify its name in the upstream-public-key
parameter in .github/workflows/build.yml
, or remove the parameter to disable key verification.
Container signing is important for end-user security and is fully supported by the CI. By default, the CI will check the signature of your base image to make sure it hasn't been tampered with. You can also sign your own image to give your users the same security guarantees.
If you'd like to sign your images using Cosign:
- Generate a cosign key:
Leave the password blank. The keys will be in
podman run --rm -it -v /tmp:/cosign-keys bitnami/cosign generate-key-pair
/tmp/cosign.{key,pub}
. - Add
cosign.pub
to the repository as/cosign.pub
, commit, and push. This file is public and needed for signature verification. NEVER commit yourcosign.key
to the repo!! - In GitHub repo settings, go to "Secrets and variables" > "Actions". Create a secret called
SIGNING_SECRET
and paste the contents ofcosign.key
. Storecosign.key
securely and delete it from/tmp
. You can also do this via the GitHub CLI:gh secret set SIGNING_SECRET < cosign.key
By default, the CI uploads built ISO images as GitHub Artifacts. These can be large, and artifact storage is limited, so you may want to upload ISOs to Cloudflare R2 (free tier).
Follow these steps:
- Sign up for Cloudflare R2 and create a new bucket. Use any name and location; the free tier only supports the Standard storage class.
- Create an API token with "Object Read & Write" permissions, limited to your new bucket. Save the Access Key ID and Secret Access Key.
- Add the following repository secrets in GitHub:
R2_ACCOUNT_ID
: Your Cloudflare account ID (found in the dashboard URL:https://dash.cloudflare.com/<R2_ACCOUNT_ID>/home
)ACCESS_KEY_ID
: The Access Key ID from your API tokenSECRET_ACCESS_KEY
: The Secret Access Key from your API tokenBUCKET
: Your bucket name
- Update your workflow:
In the
build-iso
job ofbuild-iso.yml
, uncomment the secret definitions for these secrets and setupload-to-cloudflare: true
in the workflow inputs:upload-to-cloudflare: true
- Enable public access (optional): In the Cloudflare dashboard, select your R2 bucket and enable the "Public Development URL" if you want to share ISOs publicly. This gives you a URL prefix for downloads.
Now you're ready to make your respin your own!
Place any files you want to include in your image in /files/system/
. The
directory structure and permissions will be preserved. This is ideal for adding themes,
backgrounds, configuration files, etc.
Scripts in /files/scripts/
are run during image creation. The build.sh
script copies files from /files/system/
into the image, then runs all scripts in order,
and finally runs cleanup.sh
.
- Start by editing
10-base.sh
to suit your needs. - Add more scripts as needed, using the naming scheme
XX-whatever.sh
(whereXX
is a number). - Do not modify
build.sh
,cleanup.sh
,90-signing.sh
, or91-image-info.sh
unless you know what you're doing.
After adding your files and scripts, commit your changes. The CI will build a new image for you automatically. You can also build locally:
make image
The provided Makefile
includes several useful commands for local development and testing:
make image
: Build the container image using Podman.make clean
: Remove the./output
directory and build artifacts.make iso
: Build a bootable ISO image using bootc-image-builder.make qcow2
: Build a QCOW2 disk image using bootc-image-builder.make run-qemu-iso
: Boot the generated ISO in QEMU for testing. Creates a virtual disk if needed.make run-qemu-qcow
: Boot the generated QCOW2 disk image in QEMU for testing.make run-qemu
: Boot the raw disk image in QEMU (after installation).
Note: You may need
sudo
privileges and Podman installed. For more details, see theMakefile
. QEMU is only optionally needed for local testing.
Your respin is designed to work with bootc, a tool for managing and updating container-based operating system images. Here are some basics to get you started:
Build or download the ISO for your image, boot into it and follow the installation procedure.
Caution
This is entirely unsupported and may not work at all. In fact, it probably doesn't work at all and it's a terrible idea to even try. Don't do this.
If you're already running a bootc image and wish to change to this one, you may be able to do
this via bootc switch
. As you won't have the correct signing key or configuration, you'll
have to disable it first:
sudo cp /etc/containers/policy.json /etc/containers/policy.json.old
sudo echo '{"default": [{"type": "insecureAcceptAnything"}]}' > /etc/containers/policy.json
sudo bootc switch --transport registry <REGISTRY>/<IMAGE_PATH>/<IMAGE_NAME>:latest
(fill in <REGISTRY>/<IMAGE_PATH>/<IMAGE_NAME>
with your actual bootc image location)
After this, reboot into your new image. Now we can fix it to enforce key verification
with the new image's policy.json
:
sudo cp /usr//etc/containers/policy.json /etc/containers/policy.json
Now your image should be able to update itself correctly. Or not at all. Remember, this is entirely unsupported!!
Once installed, your system will automatically check for updates in the background using a systemd unit provided by bootc. You can also manually trigger an upgrade:
sudo bootc upgrade
This will pull the latest image and prepare it for the next boot. On reboot, the system will run the new image version.
- To see the current image and status:
bootc status
- To roll back to the previous image after an upgrade:
sudo bootc rollback
This template is set up with GitHub Actions workflows to build, test, and (optionally)
sign your images automatically on every push or pull request. See the .github/workflows/
directory for details.
- Build fails locally: Ensure you have Podman and QEMU installed, and that you have the necessary permissions (try running with
sudo
). - CI build fails: Check the Actions tab in GitHub for logs. Make sure your secrets and configuration are correct.
- Image doesn't boot in QEMU: Double-check your custom scripts and added files for errors, check the build logs for errors.