v0.2.0
xenomorph v0.2.0
Replace a running Linux root filesystem with a new one built from OCI images — live, without rebooting.
What's new
-
Native OCI registry client — xenomorph pulls container images directly using Zig's HTTP/TLS
stack. No external tools (docker, curl, skopeo) required. Supports Docker Hub, GHCR, and any
Docker-distribution-compatible registry with automatic authentication and multi-platform
image resolution (x86_64, aarch64, armv7). -
Multi-layer rootfs merging — combine multiple --image and --rootfs layers in a single
command. Later layers overwrite earlier ones on file conflicts. Entrypoint, env vars, and
working directory from OCI image configs are merged field-by-field (env merges by key). -
Build subcommand — xenomorph build creates OCI images without pivoting. Use it to pre-warm
the cache or produce images for later use with xenomorph pivot. -
Build caching — built rootfs images are cached as OCI layouts. Repeated invocations with the
same layers skip all image pulls and merging. Set CACHE_DIRECTORY or --cache-dir to control
the cache location. -
systemd rescue.target integration — run xenomorph as a systemd service that triggers on
rescue.target. A warmup service pre-pulls images during normal boot so the pivot is instant.
Ships with ready-to-use systemd unit files and a NixOS module. -
Tailscale integration — --tailscale-authkey adds the Tailscale image, creates a startup
script that runs tailscaled and authenticates, then execs your entrypoint. Combined with
--headless, this lets you pivot a remote machine over SSH and reconnect via Tailscale. -
Containerfile support — --containerfile parses Dockerfiles/Containerfiles (FROM, COPY, ADD,
ENV, WORKDIR, ENTRYPOINT, CMD, LABEL, ARG). RUN is not yet supported. -
Headless mode — --headless forks into the background before the pivot, surviving SSH
disconnection. Logs to a configurable directory.
Breaking changes
- --exec is now --entrypoint. Use --command/--cmd for arguments.
- The image argument is no longer positional. Use --image or --rootfs .
- --tailscale flag removed. Use --tailscale-authkey which implicitly adds the
tailscale image. - Default image is docker.io/library/alpine:latest when no layers are specified.
Installation
Static binaries for Linux x86_64, aarch64, and armv7:
curl -LO
https://github.com/ananthb/xenomorph/releases/download/v0.2.0/xenomorph-x86_64-linux
chmod +x xenomorph-x86_64-linux
sudo mv xenomorph-x86_64-linux /usr/local/bin/xenomorph
Or with Nix:
nix run github:ananthb/xenomorph
Quick start
# Pivot to alpine (default)
sudo xenomorph pivot
# Pivot with Tailscale over SSH
sudo xenomorph pivot --headless --tailscale-authkey tskey-auth-xxxxx
# Pre-warm the cache
sudo xenomorph build --image alpine:latest --tailscale-authkey tskey-auth-xxxxx
# Build an OCI image
sudo xenomorph build --image alpine:latest --rootfs ./extra-files/ -o my-image.oci
Full Changelog: v0.1.0...v0.2.0