Immutable Fedora CoreOS images and installers for workstations, storage nodes, and VM guests. Just contains the build recipes; Pipeline connects them into dependency graphs.
just offline [selection] [architecture]
# selection: all (default), workstation, sway, nas
# architecture: native (default), both, amd64, arm64
just offline workstation amd64
just offline amd64
# Boot a persistent AMD64 test VM from an already-built installer:
just vm workstation
just vm workstation onlineOffline builds start or reuse a local registry and embed the matching OCI image inside each installer. Architecture graphs run sequentially while independent branches within a graph run in parallel.
just vm installs into a new virtual disk on its first run and boots that disk
on subsequent runs. It includes a virtual TPM for the installer's encrypted
disk, and keeps the ISO attached for the offline image rebase. Offline VMs have
no network; online VMs use user networking. See
Workstation VM testing for requirements and settings.
For NAS-hosted services, see NAS virtual machines. The
Immich photo VM adds photo search, face grouping, and
phone uploads alongside Minecraft, with home access through photos.vm.
The IPS base embeds a pinned copy of the restricted Ansible policy runtime;
Workstation, Sway, and NAS inherit it. The image bundles ansible-core, roles,
and templates for offline local execution against the mounted host paths. It has no network, no host PID
namespace, no privileged mode, and no host-root mount. Only the host paths
needed by each profile are mounted.
sudo systemctl start infrastructure-policy.service
sudo journalctl -u infrastructure-policy.service -bThe Workstation profile manages local home ownership, additive skeleton files,
and NUT client configuration. Sway uses that profile with its own /etc/skel.
The NAS profile manages NUT configuration. SELinux changes, Btrfs subvolumes,
mounts, backups, and Flatpak updates stay in native host units. Separate
restricted clamav-prepare, suricata-prepare, and gssproxy-prepare Quadlets
use Ansible for service directories, bundled seed files, and compatibility
links. Signature/rule downloads and SELinux activation remain native.
Run just test-policy (or pipeline test-policy) to build the policy image
and exercise all profiles in disposable host trees under runtime restrictions.
GitHub and GitLab CI run these tests on AMD64 and ARM64. Image builds run the
same fixtures before publishing the runtime.
Run the same check pipeline as GitHub Actions locally:
source images/nas/pipeline.sh
PIPELINE_PULL=newer pipeline --cap-jobs 3 checkThis runs every source check and container validation job, including the checks
in just check-vm and just check-online; it does not build or publish release
images. Pipeline and Just come from the
Pipeline image, while recipes execute on the host. Quadlet generation always
uses the digest-pinned Fedora CoreOS image in test/quadlet-image (Podman 5.8.4),
including on Ubuntu runners with older Podman. Rootless Podman is required; the
first run downloads that image and later runs reuse it offline. The generator
container has no network or extra capabilities and only reads temporary copies
of the Quadlets. It validates all roles and rejects an invalid fixture; missing
tools or failed pulls fail the check rather than silently skipping validation.
Update the FCOS version and multi-architecture manifest digest together when
changing the compatibility baseline, then rerun this pipeline.
Git hooks run check-source: formatting, shell syntax, workstation tests,
build-selection tests and VM/application/lifecycle fixtures. They need the
installed Pipeline/Just tools, but do not require Podman or image downloads, so
commits also work from editors without a container runtime. check-vm-source
runs just the VM fixtures; check-vm still includes real Quadlet generation.
The full check pipeline remains mandatory in CI and additionally tests a real
commit with Podman unavailable. No hook bypass is needed.
Online builds default to IMAGE_NAMESPACE=ghcr.io/noobping. GitHub Actions
uses that namespace; GitLab CI overrides it with its project container
registry. Authenticate the container tools with REGISTRY_USER and
REGISTRY_TOKEN. Publishing to a non-local registry requires PUBLISH=true
and a clean checkout; ALLOW_DIRTY=true is available for an intentional
development build. Manifest signing uses Cosign's ambient keyless credentials
from GitHub or GitLab.com OIDC. Set SIGN_IMAGES=false for an unsigned or
self-managed test registry and REGISTRY_TLS_VERIFY=false for an insecure
local registry.
Image builds need host Podman and Buildah, plus Skopeo for split-runner manifest publication, Cosign when signing is enabled, sufficient disk space, and QEMU/binfmt when building a non-native architecture. Release uses an installed GitHub CLI or Podman. Build execution refreshes upstream images, packages, and Fedora CoreOS media, so it requires network access. “Offline” means the resulting installer can install without a network connection. The ARM64 NAS image and installer are supported; its bundled libvirt VM deployment remains x86_64-only.