KAMOS: gaming OS based on Bazzite stable, built via Forgejo Actions + Coolify runner
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
commit
6e3878f8c0
10 changed files with 338 additions and 0 deletions
56
.forgejo/workflows/build-iso.yml
Normal file
56
.forgejo/workflows/build-iso.yml
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
name: Build KAMOS installer ISO
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
variant:
|
||||||
|
description: "Which variant to build an ISO for"
|
||||||
|
required: true
|
||||||
|
default: "kamos"
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- kamos # AMD / Intel graphics
|
||||||
|
- kamos-nvidia # NVIDIA graphics
|
||||||
|
|
||||||
|
env:
|
||||||
|
# CHANGE_ME: your Forgejo domain (no https://)
|
||||||
|
REGISTRY_HOST: git.example.com
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-iso:
|
||||||
|
name: ISO for ${{ inputs.variant }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set image ref
|
||||||
|
run: |
|
||||||
|
echo "OWNER=${GITHUB_REPOSITORY_OWNER,,}" >> "$GITHUB_ENV"
|
||||||
|
echo "DATE_TAG=$(date +%Y%m%d)" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- name: Build ISO with bootc-image-builder
|
||||||
|
# Runs as a sibling container on the host Docker daemon (needs the
|
||||||
|
# kamos package set to PUBLIC in Forgejo so it can pull the image).
|
||||||
|
run: |
|
||||||
|
docker volume rm -f kamos-bib-output 2>/dev/null || true
|
||||||
|
docker volume create kamos-bib-output
|
||||||
|
docker run --rm --privileged \
|
||||||
|
-v kamos-bib-output:/output \
|
||||||
|
quay.io/centos-bootc/bootc-image-builder:latest \
|
||||||
|
--type anaconda-iso \
|
||||||
|
"${REGISTRY_HOST}/${OWNER}/${{ inputs.variant }}:stable"
|
||||||
|
|
||||||
|
- name: Extract ISO from volume
|
||||||
|
run: |
|
||||||
|
docker create --name kamos-bib-extract -v kamos-bib-output:/output alpine
|
||||||
|
docker cp "kamos-bib-extract:/output/bootiso/install.iso" \
|
||||||
|
"./${{ inputs.variant }}-${DATE_TAG}.iso"
|
||||||
|
docker rm kamos-bib-extract
|
||||||
|
docker volume rm kamos-bib-output
|
||||||
|
|
||||||
|
- name: Upload ISO to Forgejo package registry
|
||||||
|
run: |
|
||||||
|
ISO="${{ inputs.variant }}-${DATE_TAG}.iso"
|
||||||
|
curl --fail -u "${{ secrets.REGISTRY_USER }}:${{ secrets.REGISTRY_TOKEN }}" \
|
||||||
|
--upload-file "$ISO" \
|
||||||
|
"https://${REGISTRY_HOST}/api/packages/${OWNER}/generic/kamos-iso/${DATE_TAG}/${ISO}"
|
||||||
|
echo "ISO available at: https://${REGISTRY_HOST}/${OWNER}/-/packages/generic/kamos-iso/${DATE_TAG}"
|
||||||
59
.forgejo/workflows/build.yml
Normal file
59
.forgejo/workflows/build.yml
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
name: Build KAMOS images
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths-ignore:
|
||||||
|
- "README.md"
|
||||||
|
schedule:
|
||||||
|
# Weekly rebuild so KAMOS picks up upstream Bazzite stable updates
|
||||||
|
- cron: "0 6 * * 2"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
# CHANGE_ME: your Forgejo domain (no https://)
|
||||||
|
REGISTRY_HOST: git.example.com
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build ${{ matrix.image_name }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- image_name: kamos
|
||||||
|
base_image: ghcr.io/ublue-os/bazzite
|
||||||
|
- image_name: kamos-nvidia
|
||||||
|
base_image: ghcr.io/ublue-os/bazzite-nvidia
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set image ref
|
||||||
|
run: |
|
||||||
|
echo "IMAGE=${REGISTRY_HOST}/${GITHUB_REPOSITORY_OWNER,,}/${{ matrix.image_name }}" >> "$GITHUB_ENV"
|
||||||
|
echo "DATE_TAG=$(date +%Y%m%d)" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- name: Build image (uses host Docker via mounted socket)
|
||||||
|
run: |
|
||||||
|
docker build \
|
||||||
|
--build-arg BASE_IMAGE="${{ matrix.base_image }}" \
|
||||||
|
--build-arg BASE_TAG=stable \
|
||||||
|
-t "${IMAGE}:stable" \
|
||||||
|
-t "${IMAGE}:latest" \
|
||||||
|
-t "${IMAGE}:${DATE_TAG}" \
|
||||||
|
.
|
||||||
|
|
||||||
|
- name: Push to Forgejo container registry
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.REGISTRY_TOKEN }}" | \
|
||||||
|
docker login "${REGISTRY_HOST}" -u "${{ secrets.REGISTRY_USER }}" --password-stdin
|
||||||
|
for tag in stable latest "${DATE_TAG}"; do
|
||||||
|
docker push "${IMAGE}:${tag}"
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Clean up build cache (keep server disk healthy)
|
||||||
|
if: always()
|
||||||
|
run: docker image prune -f
|
||||||
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
* text=auto eol=lf
|
||||||
|
*.sh text eol=lf
|
||||||
|
Containerfile text eol=lf
|
||||||
|
*.yml text eol=lf
|
||||||
|
*.toml text eol=lf
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
output/
|
||||||
|
*.iso
|
||||||
22
Containerfile
Normal file
22
Containerfile
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# KAMOS — gaming OS built on top of Bazzite (stable channel)
|
||||||
|
#
|
||||||
|
# BASE_IMAGE is switched by CI to build the two variants:
|
||||||
|
# ghcr.io/ublue-os/bazzite -> KAMOS (AMD / Intel graphics)
|
||||||
|
# ghcr.io/ublue-os/bazzite-nvidia -> KAMOS NVIDIA (proprietary driver)
|
||||||
|
ARG BASE_IMAGE="ghcr.io/ublue-os/bazzite"
|
||||||
|
ARG BASE_TAG="stable"
|
||||||
|
|
||||||
|
FROM ${BASE_IMAGE}:${BASE_TAG}
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.title="KAMOS"
|
||||||
|
LABEL org.opencontainers.image.description="KAMOS — stable Linux gaming OS for PCs and laptops, based on Bazzite stable"
|
||||||
|
LABEL org.opencontainers.image.vendor="KAMOS"
|
||||||
|
|
||||||
|
# Overlay static files (branding, configs) onto the image
|
||||||
|
COPY system_files /
|
||||||
|
|
||||||
|
# Run the build script (install packages, rebrand, tweak defaults)
|
||||||
|
COPY build_files /tmp/build_files
|
||||||
|
RUN bash /tmp/build_files/build.sh && \
|
||||||
|
rm -rf /tmp/build_files && \
|
||||||
|
ostree container commit
|
||||||
135
README.md
Normal file
135
README.md
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
# KAMOS — Gaming Linux OS
|
||||||
|
|
||||||
|
KAMOS is a custom Linux gaming operating system for PCs and laptops, built on top of
|
||||||
|
[Bazzite](https://bazzite.gg)'s **stable** channel (Fedora Atomic). It is an
|
||||||
|
*image-based* OS: the whole system ships as one tested image, updates are atomic,
|
||||||
|
and you can roll back from the boot menu if an update ever misbehaves.
|
||||||
|
|
||||||
|
Everything Bazzite ships is included out of the box: Steam with Proton, Gamescope,
|
||||||
|
MangoHud, GameMode, HDR/VRR support, the fsync gaming kernel, KDE Plasma, Distrobox,
|
||||||
|
and Waydroid.
|
||||||
|
|
||||||
|
KAMOS is built and hosted entirely on **your own Forgejo instance** — Forgejo
|
||||||
|
Actions builds the images, and Forgejo's container/package registry serves them.
|
||||||
|
The build runner is deployed as a **Coolify service** (your existing Forgejo is
|
||||||
|
not modified in any way).
|
||||||
|
|
||||||
|
## Variants
|
||||||
|
|
||||||
|
| Image | For |
|
||||||
|
|---|---|
|
||||||
|
| `kamos` | AMD and Intel graphics (uses built-in Mesa drivers) |
|
||||||
|
| `kamos-nvidia` | NVIDIA graphics (proprietary driver pre-installed) |
|
||||||
|
|
||||||
|
Both work on desktops and laptops. For laptops with hybrid AMD+NVIDIA or
|
||||||
|
Intel+NVIDIA graphics, use `kamos-nvidia`.
|
||||||
|
|
||||||
|
## One-time setup
|
||||||
|
|
||||||
|
Server needs **~40 GB free disk** and 4+ GB RAM. Coolify's job here is only to
|
||||||
|
run the build runner container — the runner connects to Forgejo with a token;
|
||||||
|
your existing Forgejo service is untouched.
|
||||||
|
|
||||||
|
### 1. Get a runner registration token from Forgejo
|
||||||
|
|
||||||
|
Forgejo → **Site administration → Actions → Runners → Create new runner** →
|
||||||
|
copy the registration token. (This only *creates a token*; it changes nothing.)
|
||||||
|
|
||||||
|
### 2. Deploy the runner in Coolify
|
||||||
|
|
||||||
|
Coolify → your project → **New Resource** → search `git` → select **Gitea Runner**
|
||||||
|
(Forgejo's Actions runner is compatible with Gitea's — there is no separate
|
||||||
|
Forgejo Runner template). Before deploying, set the environment variables:
|
||||||
|
|
||||||
|
| Variable | Value |
|
||||||
|
|---|---|
|
||||||
|
| `GITEA_INSTANCE_URL` | `https://YOUR-FORGEJO-DOMAIN` |
|
||||||
|
| `GITEA_RUNNER_REGISTRATION_TOKEN` | the token from step 1 |
|
||||||
|
| `GITEA_RUNNER_NAME` | `kamos-builder` |
|
||||||
|
| `GITEA_RUNNER_LABELS` | `ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-22.04` |
|
||||||
|
|
||||||
|
(`GITEA_TOKEN` can stay empty — it's an alternative to the registration token.)
|
||||||
|
|
||||||
|
Then, still in the service before/after first deploy:
|
||||||
|
|
||||||
|
1. **Storages → Add File Mount**: destination `/config.yaml`, content = the file
|
||||||
|
[`coolify/runner-config.yaml`](coolify/runner-config.yaml) from this repo.
|
||||||
|
This lets build jobs use the host Docker daemon (required).
|
||||||
|
2. Add env var `CONFIG_FILE=/config.yaml`.
|
||||||
|
3. Deploy. In Forgejo → Site administration → Runners, `kamos-builder` should
|
||||||
|
appear as **online** with the `ubuntu-latest` label.
|
||||||
|
|
||||||
|
### 3. Configure the repo
|
||||||
|
|
||||||
|
1. Create a repository named `kamos` on your Forgejo and push this folder to it
|
||||||
|
(make sure Repository → Settings → **Actions** is enabled).
|
||||||
|
2. In both workflow files under `.forgejo/workflows/`, change
|
||||||
|
`REGISTRY_HOST: git.example.com` to your Forgejo domain.
|
||||||
|
3. In Forgejo: your avatar → **Settings → Applications → Generate new token**
|
||||||
|
with `package` read/write scope. Then in the repo:
|
||||||
|
**Settings → Actions → Secrets**, add:
|
||||||
|
- `REGISTRY_USER` — your Forgejo username
|
||||||
|
- `REGISTRY_TOKEN` — the token you just generated
|
||||||
|
4. Push to `main` — the **Build KAMOS images** workflow builds both variants
|
||||||
|
(30–60 min first run; the ~8 GB Bazzite base download is cached after that).
|
||||||
|
5. After the first build: profile → **Packages** → `kamos` and `kamos-nvidia` →
|
||||||
|
package settings → visibility **Public** (so installed machines and the ISO
|
||||||
|
builder can pull without credentials).
|
||||||
|
|
||||||
|
### 4. Build an installer ISO
|
||||||
|
|
||||||
|
Repo → **Actions → Build KAMOS installer ISO → Run workflow** → pick `kamos` or
|
||||||
|
`kamos-nvidia`. The finished ISO is uploaded to your Forgejo **package registry**
|
||||||
|
under `kamos-iso` — download it from your profile's Packages page.
|
||||||
|
|
||||||
|
The weekly scheduled rebuild keeps KAMOS current with upstream Bazzite stable and
|
||||||
|
Fedora security updates; installed machines pick these up automatically.
|
||||||
|
|
||||||
|
## Installing
|
||||||
|
|
||||||
|
**Fresh install:** write the ISO to a 16 GB+ USB stick with
|
||||||
|
[Fedora Media Writer](https://fedoraproject.org/workstation/download) or
|
||||||
|
[Rufus](https://rufus.ie) (DD mode), boot from it, and follow the installer.
|
||||||
|
|
||||||
|
**Already running Bazzite / Fedora Atomic?** Rebase without reinstalling:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rpm-ostree rebase ostree-unverified-registry:YOUR-FORGEJO-DOMAIN/YOUR-USERNAME/kamos:stable
|
||||||
|
```
|
||||||
|
|
||||||
|
(use `kamos-nvidia:stable` for NVIDIA), then reboot.
|
||||||
|
|
||||||
|
> **Secure Boot:** Bazzite's kernel is signed with Universal Blue's key. Either
|
||||||
|
> disable Secure Boot in the BIOS, or enroll the key as described in the
|
||||||
|
> [Bazzite docs](https://docs.bazzite.gg/General/Installation_Guide/secure_boot/).
|
||||||
|
|
||||||
|
## Customizing KAMOS
|
||||||
|
|
||||||
|
- **Add packages baked into the OS:** edit `build_files/build.sh`
|
||||||
|
(`dnf5 -y install <package>`), push — CI rebuilds the image.
|
||||||
|
- **Add config files:** drop them under `system_files/` mirroring the target
|
||||||
|
path (e.g. `system_files/etc/foo.conf` → `/etc/foo.conf`).
|
||||||
|
- **Apps like Heroic, Lutris, Discord, OBS:** install as Flatpaks after boot
|
||||||
|
(Discover app store) — that's the intended pattern on image-based systems.
|
||||||
|
- **Download page:** if you want a public KAMOS website with download links,
|
||||||
|
deploy a small static site with Coolify pointing at the ISO URLs in your
|
||||||
|
Forgejo package registry.
|
||||||
|
|
||||||
|
## Building locally (optional)
|
||||||
|
|
||||||
|
Requires Linux or WSL2 with `podman` or `docker`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker build --build-arg BASE_IMAGE=ghcr.io/ublue-os/bazzite --build-arg BASE_TAG=stable -t kamos:stable .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
Containerfile OS image recipe (FROM bazzite:stable)
|
||||||
|
build_files/build.sh packages + branding applied at build time
|
||||||
|
system_files/ files overlaid onto the OS (/etc, /usr, ...)
|
||||||
|
disk_config/iso.toml installer ISO configuration (optional kickstart)
|
||||||
|
coolify/runner-config.yaml runner config for the Coolify Gitea Runner service
|
||||||
|
.forgejo/workflows/ CI: image build + ISO build (Forgejo Actions)
|
||||||
|
```
|
||||||
35
build_files/build.sh
Normal file
35
build_files/build.sh
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# KAMOS build script — runs once at image build time (not on user machines).
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
### ---------------------------------------------------------------
|
||||||
|
### 1. Branding: rename the OS to KAMOS
|
||||||
|
### (NAME/PRETTY_NAME only — ID/VERSION stay untouched so Bazzite
|
||||||
|
### and Fedora tooling keeps working)
|
||||||
|
### ---------------------------------------------------------------
|
||||||
|
sed -i 's/^NAME=.*/NAME="KAMOS"/' /usr/lib/os-release
|
||||||
|
sed -i 's/^PRETTY_NAME=.*/PRETTY_NAME="KAMOS (Gaming Edition)"/' /usr/lib/os-release
|
||||||
|
|
||||||
|
### ---------------------------------------------------------------
|
||||||
|
### 2. Extra packages layered on top of Bazzite
|
||||||
|
### Bazzite stable already ships: Steam, Gamescope, Proton (via
|
||||||
|
### Steam), MangoHud, vkBasalt, gamemode, Lutris deps, Waydroid,
|
||||||
|
### Distrobox, KDE Plasma, HDR/VRR support, fsync kernel.
|
||||||
|
### Add anything extra you want baked into the OS here.
|
||||||
|
### ---------------------------------------------------------------
|
||||||
|
dnf5 -y install \
|
||||||
|
btop \
|
||||||
|
fastfetch
|
||||||
|
|
||||||
|
# Examples (uncomment to include):
|
||||||
|
# dnf5 -y install openrgb # RGB peripheral control
|
||||||
|
# dnf5 -y install corectrl # AMD GPU/CPU tuning UI
|
||||||
|
# dnf5 -y install input-remapper # remap controller/keyboard
|
||||||
|
|
||||||
|
### ---------------------------------------------------------------
|
||||||
|
### 3. System defaults
|
||||||
|
### ---------------------------------------------------------------
|
||||||
|
# Enable weekly automatic OS updates (staged, applied on reboot)
|
||||||
|
systemctl enable rpm-ostreed-automatic.timer || true
|
||||||
|
|
||||||
|
echo "KAMOS build complete."
|
||||||
11
coolify/runner-config.yaml
Normal file
11
coolify/runner-config.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
# act_runner / Forgejo runner config — paste this as a File Mount in the
|
||||||
|
# Coolify "Gitea Runner" service at /config.yaml, and add env CONFIG_FILE=/config.yaml
|
||||||
|
#
|
||||||
|
# Purpose: lets the job containers reach the host Docker daemon, which the
|
||||||
|
# KAMOS workflows need for `docker build` and bootc-image-builder.
|
||||||
|
log:
|
||||||
|
level: info
|
||||||
|
container:
|
||||||
|
options: "-v /var/run/docker.sock:/var/run/docker.sock"
|
||||||
|
valid_volumes:
|
||||||
|
- /var/run/docker.sock
|
||||||
10
disk_config/iso.toml
Normal file
10
disk_config/iso.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# bootc-image-builder config for the KAMOS installer ISO.
|
||||||
|
# The generated ISO uses the Anaconda installer (same as Fedora/Bazzite):
|
||||||
|
# the user picks disk, username and password during install.
|
||||||
|
|
||||||
|
# Example: preset keyboard/locale (uncomment and edit if wanted)
|
||||||
|
# [customizations.installer.kickstart]
|
||||||
|
# contents = """
|
||||||
|
# keyboard us
|
||||||
|
# lang en_US.UTF-8
|
||||||
|
# """
|
||||||
3
system_files/etc/motd
Normal file
3
system_files/etc/motd
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
Welcome to KAMOS — Gaming Edition
|
||||||
|
Based on Bazzite stable (Fedora Atomic). Updates are atomic; roll back
|
||||||
|
from the boot menu if anything breaks.
|
||||||
Loading…
Reference in a new issue