A minimal app and its Unit config baked onto the freeunit-php base image via a
small Dockerfile, then run with the hardening recommended in the
top-level README. Nothing is bind-mounted — the
container is self-contained.
docker compose up --build # from this directoryThen open http://localhost:8080/.
Equivalent without compose:
docker build -t freeunit-php-example .
docker run --rm -p 8080:8080 \
--cap-drop=ALL --cap-add=SETUID --cap-add=SETGID \
--security-opt=no-new-privileges \
freeunit-php-exampleDockerfile—FROMthe published GHCR base, thenCOPY www/(the app, includingindex.php) to/www/andconfig.jsonto/docker-entrypoint.d/. The entrypoint applies that config on first start; no runtime mounts.- Hardening —
cap_drop: [ALL]thencap_add: [SETUID, SETGID]plusno-new-privileges: the Unit master starts as root and needs only those two capabilities to drop each worker to the app user/group. config.jsonsets the application'suser/grouptofreeunit, so the PHP worker itself runs unprivileged (the recommended way to drop privileges — not by changing the container user).