File Ownership

ilo mounts your project directory into the container read-write, so the build tools inside the container (compilers, package managers, …) work on your real source and the artifacts they produce land back in your working directory. The natural question is: when something inside the container creates or edits a file, who owns it on the host? Many build images run as root, and you do not want to end up with root-owned files in your checkout that you then need sudo to delete.
The good news is that with ilo’s default runtime this just works — and where it does not, it is a property of the container runtime, not of ilo.
Rootless Podman (recommended)
On Linux ilo selects Podman first, and rootless Podman runs the container inside a user namespace that maps the container’s root (UID 0) to your host user.
Images that run as root (most build images — Maven, Node, GCC, …): there is nothing to do. The container is root inside — so it can write the image’s root-owned caches and tools, e.g. Maven’s /root/.m2 — while those writes map to your UID outside, so files in your project are owned by you. This “root inside, you outside” mapping is exactly what makes a container-based build environment pleasant, and it is the default.
Images that run as a fixed non-root user are the exception. Without help, their writes land on the host under a high “phantom” sub-UID (from your /etc/subuid range) that you cannot easily edit or delete. Map that user back to yourself with Podman’s --userns=keep-id:
$ ilo shell --runtime-run-option=--userns=keep-id my-nonroot-image
or simply --current-user, which ilo translates to the right mechanism for the selected runtime. You can instead set userns = "keep-id" globally in containers.conf, but be aware that makes every container run as your non-root user — which removes the “root inside” benefit above and can break images that genuinely need root. Prefer the per-run flag.
What :z does (and does not) do
When it mounts your project directory, ilo appends :z to the volume. That is purely an SELinux relabel so the container is allowed to access the directory on systems like Fedora and RHEL — it has nothing to do with UID ownership. The two concerns are independent: :z grants access, the user namespace decides ownership.
Docker
The Docker daemon runs as real root and does not remap UIDs for bind mounts by default, so a container running as root writes host files owned by root.
The clean fix is to run Docker in rootless mode, which gives you the same user-namespace mapping as rootless Podman — the problem then disappears the same way, with no per-command flags.
If you cannot use rootless Docker, pass --current-user. ilo runs your work by execing into a long-lived container, so the user mapping has to apply to both the container and every exec — --current-user does that (a raw --runtime-run-option=--user=… would only cover the container’s main process, not the shell you actually work in). The trade-off still stands: as a non-root user the image’s root-owned paths (for example a cache under /root) may not be writable, so point such tools at a writable location — your mounted working directory, a $HOME you own, or a dedicated cache volume. For build images that insist on root, rootless Docker remains the smoother path.
To make this easy to discover, when ilo opens a shell on a rootful Docker daemon without --current-user, it prints a one-line hint pointing you here. Rootless Docker (and Podman/nerdctl) already map the host user, so no hint is shown there; passing --current-user also silences it.
Not mounting at all
If a particular run should not touch your working directory, pass --no-mount-project-dir to skip the mount entirely.