Instant MicroVMs/Unikernels for macOS and Linux
linux unikernel unikraft osv freebsd netbsd microvm libkrun
README.md

unikraft-php #

PHP 8.2 (CLI) serving HTTP from a raw socket loop, running as a Unikraft unikernel. Ported from unikraft-cloud/examples's httpserver-php8.2 to build for arm64 as well as x86_64 and boot under bsdkrun.

bsdkrun pack .                # host arch; or: bsdkrun pack . --target x86_64
bsdkrun unikraft . --mem 512 --port 8080:8080 \
  --cmdline "elfloader -- /usr/local/bin/php /usr/src/server.php"
$ curl http://127.0.0.1:8080/
Hello, World!

Status #

arm64 works. The unikernel boots, DHCPs an address, the server starts and answers over the forwarded port with Hello, World!. x86_64 has never been run; .github/workflows/e2e-unikraft-examples.yml runs it as strict: false until its first green run.

server.php is upstream's, verbatim: a single process accepting one connection at a time over the sockets extension. Extra words in $argv (libkrun appends some — see ../unikraft-redis/README.md) are ignored by the script, so no trampoline is needed.

Differences from upstream #

No runtime: base-compat:latest. Upstream pulls a prebuilt Unikraft Cloud kernel, which is published for x86_64 only. The Kraftfile here builds the equivalent runtime (library/base from unikraft/catalog) from source, plus the arm64 fixes in ../../library/unikraft-base.

The Dockerfile resolves its libraries instead of listing them. Upstream enumerates 45 /lib/x86_64-linux-gnu/... paths (and pins --platform=linux/x86_64 to make that true); on arm64 those paths do not exist. ldd — over the php binary and every extension .so, since extensions are dlopen()ed and would otherwise have unresolved libraries — keeps the list correct on both architectures.

Only the extension directory ships from /usr/local/lib/php. The rest of that tree is PEAR, which nothing here uses; every megabyte is paid for twice at boot (embedded in the kernel image, unpacked into ramfs).

Layout #

file role
php.ini loads the sockets extension; compiled-in defaults otherwise
server.php upstream's socket-loop HTTP server, verbatim