Library images

GoNIX can also disappear. A Library image is a Go program packaged with a slim kernel and a small init as one bootable ISO, without a shell, coreutils or any other userland. It boots on a cloud that takes custom ISOs, from a disk or USB stick, or on your laptop with QEMU, and the program is all there is.

Any Go program, unmodified

gonix pack builds the package you point it at (., an import path, or pkg@version) with your own Go toolchain, for amd64 or arm64. Anything that builds with CGO_ENABLED=0 works as it is, and packing needs neither Docker nor root.

One file, boots anywhere

The image is a single hybrid ISO: BIOS and UEFI from a CD, the same from a disk or USB stick, and a direct boot under gonix run. Upload it to a cloud as a custom ISO and it boots there.

Small and quick

A kernel configured for virtual machines and nothing else: about 4 MB on amd64 and 9 MB on arm64. On arm64 it reaches init in a tenth of a second, and init has the program running in milliseconds.

Supervised, and stops when it’s done

Init restarts a program that fails, with backoff, and powers the machine off once nothing is left to run, so a job VM does its job and stops, and gonix run exits with the program’s status. ^C shuts down cleanly through the power button, as a cloud’s “stop” does.

Configured at boot

One image, many deployments: an env file of KEY=value lines sets the program’s environment, the hostname and a static address. It can come from a cloud’s user-data, a seed disk, or gonix run -config.

Logs where you look

Output goes to every console, a cloud’s web console included, and with GONIX_SYSLOG to your syslog server as RFC 5424, early boot and all.

Try it

go install git.mills.io/prologic/gonix/cmd/gonix@latest
git clone https://git.mills.io/prologic/gonix && cd gonix
gonix run -p 8080:8080 ./examples/library/hello
curl http://127.0.0.1:8080/

You need Go, and QEMU to run images on your machine. gonix run -firmware uefi boots the ISO through firmware and its bootloader, exactly as a cloud does, and gonix run -debug adds a shell and SSH for poking around.

Configuration at boot

GREETING=Howdy                     # environment for the program
GONIX_HOSTNAME=web-1               # the system
GONIX_IP=192.0.2.10/24             # a static address instead of DHCP
GONIX_GATEWAY=192.0.2.1
GONIX_DNS=192.0.2.53
GONIX_SYSLOG=logs.example.com:514  # send output to syslog too
GONIX_ETH1_IP=172.16.0.5/20        # a private network on a second interface

Pass it with gonix run -config prod.env hello.iso, or paste it into a cloud instance’s user-data. Init reads it from the kernel command line, a NoCloud seed disk, or, on a cloud it recognises, the metadata service.

Interfaces beyond eth0 are configured too: from a GONIX_ETH<n>_IP key, on Vultr from the instance’s metadata (so a VPC just works), or by DHCP. The default route and DNS stay on eth0.

How it works

A Library image is a kernel, an initramfs and a hybrid ISO around them. The initramfs holds libinit, GoNIX’s init cut down to what a single program needs: mount the kernel filesystems, bring up the network, mount a data disk at /data if there is one, start and supervise the programs, report how they ended, power off. The kernel and the bootloaders come from the GoNIX package repository, checksummed and cached, so packing needs nothing but Go.

Every flag, the boot sequence, and the design decisions with their reasons are in docs/library-images.md.