Building your own Edera zone kernel
Want full control over the kernel that runs inside your Edera zones? This guide walks you through building your own Linux kernel OCI image using Edera’s open-source tooling—either via GitHub Actions or locally on your machine.
Why build your own zone kernel?
Edera’s default zone kernel is fast, secure, and hardened—but you may want to:
- Enable or disable specific
Kconfig
options - Add out-of-tree drivers or modules
- Apply experimental kernel patches
- Debug with extra symbols or instrumentation
- Use a different upstream kernel series
Approach 1: Build kernels with GitHub Actions
Use GitHub’s infrastructure to build and publish kernel images automatically.
Step 1: Fork the repo
Fork edera-dev/linux-kernel-oci
into your GitHub org or account.
Step 2: Understand the GitHub workflow
The repo includes a workflow at:
.github/workflows/build.yaml
This will build and push kernels to the GitHub Container Registry (ghcr.io
) using the default GITHUB_TOKEN
. You can learn more about this token in GitHub’s docs.
Step 3: Update config.yaml
Edit the root-level config.yaml
:
- Change
imageNameFormat
to point to your own container registry:
imageNameFormat: "ghcr.io/<your-org>/[image]:[tag]"
-
Optionally change which flavors, variants, or kernel versions you want to build.
-
Customize Kconfig fragments in the
configs/
directory as needed.
Step 4: Trigger a build
From the Actions tab in your forked repo, run the Build Kernels
job.
In the workflow input field, specify which kernels to build:
stable:flavor=zone,host
This example builds both the zone
and host
flavors from the latest stable kernel.org
releases for all LTS kernels.
Approach 2: Build locally (for debugging or rapid iteration)
Local builds are ideal when you need full control, want to test quickly, or want to inspect output manually.
Step 1: Clone the repo
git clone https://github.com/edera-dev/linux-kernel-oci.git
cd linux-kernel-oci
Step 2: Edit config.yaml
You’ll find config.yaml
at the root of the repo. This file defines what kernels will be built, where they’ll be pushed, and for which architectures and versions. To avoid building dozens of variants you don’t care about, you’ll want to edit this file carefully:
- Set the target image registry
UpdateimageNameFormat
to a registry you control. For example, to push to a temporary test registry:
imageNameFormat: "ttl.sh/yourname/[image]:[tag]"
- Limit the architectures
By default, this repo builds for bothx86_64
andarm64
. If you only need one, reduce it:
architectures:
- x86_64
This uses Docker buildx
, so you can cross-build arm64
on x86_64
hosts and vice versa.
- Limit the flavors
You can build zone or host kernels, or both. Each has its own configuration fragment:
flavors:
- name: zone-bpf
- Limit the versions
This repo supports building across many upstream kernel.org versions. You probably don’t want them all. To build just a specific series:
versions:
- series: '5.4'
- Or build only the latest in a series
Example: build only the latest point release in 6.15 forx86_64
and push it to a ttl.sh registry:
imageNameFormat: "ttl.sh/hackben/[image]:[tag]"
architectures:
- x86_64
flavors:
- name: zone-bpf
constraints:
series:
- '6.15'
versions:
- current: true
💡 These constraints will drastically reduce build time and disk usage. Always check the generated matrix before running the build.
Step 3: Customize kernel config
Edit the Kconfig fragments in configs/
to enable or disable features. See configs/README.md
for syntax and options.
Step 4: Build the kernel
./hack/build/docker-build.sh
This script will generate the build matrix and compile your kernel using docker buildx
.
Step 5: Use the kernel image
Once built, your image will appear in docker image list
.
You can:
- Push it:
docker push ttl.sh/<your-username>/zone-kernel:6.6.15
- Inspect it:
crane export ttl.sh/<your-username>/zone-kernel:6.6.15 - --platform=linux/amd64 | tar xf - -C ./output
cd output/kernel
zcat config.gz
unsquashfs addons.squashfs
Notes on patches and flavors
- Edera carries a small number of patches, tracked in the
patches/
directory. - Not all patches apply to all kernel versions—
config.yaml
defines the version constraints. - Kernel flavors and variants are defined in
configs/
`, and support Kconfig overlays.
Troubleshooting
- Make sure
docker buildx
is installed and working for cross-builds (especially for arm64). - If builds take too long or run out of memory, reduce the matrix in
config.yaml
. - Some registry tags (like
ttl.sh
) auto-expire, which is great for one-off tests.
What’s next?
After you’ve built and published your custom kernel, you can use it in Edera zones via the CLI or Kubernetes:
protect zone launch --kernel ttl.sh/<your-username>/zone-kernel:6.6.15 ...
Or use the dev.edera/kernel
annotation in Kubernetes:
annotations:
dev.edera/kernel: ttl.sh/<your-username>/zone-kernel:6.6.15