commit 6e3878f8c076fb44cb2471600493e7865d0d851b Author: kmk1971 Date: Wed Jul 29 17:57:49 2026 +0400 KAMOS: gaming OS based on Bazzite stable, built via Forgejo Actions + Coolify runner Co-Authored-By: Claude Fable 5 diff --git a/.forgejo/workflows/build-iso.yml b/.forgejo/workflows/build-iso.yml new file mode 100644 index 0000000..303c997 --- /dev/null +++ b/.forgejo/workflows/build-iso.yml @@ -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}" diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml new file mode 100644 index 0000000..a08b1c1 --- /dev/null +++ b/.forgejo/workflows/build.yml @@ -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 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..890e01b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +* text=auto eol=lf +*.sh text eol=lf +Containerfile text eol=lf +*.yml text eol=lf +*.toml text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d78b0d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +output/ +*.iso diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..44c0948 --- /dev/null +++ b/Containerfile @@ -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 diff --git a/README.md b/README.md new file mode 100644 index 0000000..43183f1 --- /dev/null +++ b/README.md @@ -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 `), 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) +``` diff --git a/build_files/build.sh b/build_files/build.sh new file mode 100644 index 0000000..33a915a --- /dev/null +++ b/build_files/build.sh @@ -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." diff --git a/coolify/runner-config.yaml b/coolify/runner-config.yaml new file mode 100644 index 0000000..5c893ef --- /dev/null +++ b/coolify/runner-config.yaml @@ -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 diff --git a/disk_config/iso.toml b/disk_config/iso.toml new file mode 100644 index 0000000..b4b509b --- /dev/null +++ b/disk_config/iso.toml @@ -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 +# """ diff --git a/system_files/etc/motd b/system_files/etc/motd new file mode 100644 index 0000000..5ef3f73 --- /dev/null +++ b/system_files/etc/motd @@ -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.