foxbox is a simplistic, rootless process isolation runtime and CLI tool based on Linux user namespaces.
It’s a fun project created to explore and better understand what’s behind the high-level abstractions of existing container runtimes like Docker or Podman.
A lot of the initial process isolation code is based on Liz Rice’s “Containers From Scratch”, Lizzie Dixon’s Linux containers in 500 lines of code”, and runc’s libcontainer.
Note: better not use foxbox in prod. I run shady fluff in prod and even I wouldn’t run this there (yet, hehe).
Purely for fun, containers are named foxboxes (or boxes for short). Likewise, tasks in containers are just called foxes.
For now, clone the repo and then run go run ./cmd/foxbox
to access the
cli tool.
To run a foxbox, you need a compatible image. So far, I’ve only used the
alpine 3.18.4 rootfs. Download that rootfs to ./images
The
resulting file name excluding the file extention (must be .tar
or
.tar.gz
), e.g. alpine-minirootfs-3.18.4-x86_64
is the image name in
foxbox.
To create a foxbox and run a shell, execute the following in the project root:
go run ./cmd/foxbox run --rm alpine-3.18.4-x86_64
Run the hostname
to get the box name. To find the rootfs, head to
./runtime/BOXNAME/boxfs
on the host machine, where BOXNAME
is the
hostname of the box.
foxbox should be more usable out of the box (heh!).
Running foxbox run --rm alpine
should get the alpine
image for you
and spin up a box. Likewise, being able to build your own images would
add more uses to foxbox.
Right now, foxbox is a standalone CLI but this makes it more complicated for concurrent use. I see two ways forward: keep it a standalone CLI, so it’s easier to use but hard to integrate with, or separate the CLI from the engine, so it runs as daemon similar to how Docker or Podman work.
A standalone CLI would be more directly educational but having it separated would potentially allow scripting with it and using it programmatically. The latter would also prevent resource conflicts but I’m not sure how necessary that is.
While interop is really cool, I’m not planning to make foxbox compatible with the OCI runtime spec, though it might be a fun challenge later on.
- Create and delete foxboxes from rootfs tarballs
- List all foxboxes
- List running foxes
- Enter foxboxes by with nsenter
- Box inspect (analog to
podman inspect
) - Run foxes detached
- Store logs
- Isolation
- User namespaces
- Dropping kernel capabilities
- Syscall restriction with seccomp
- Standard streams (stdin, stdout, stderr)
-
/dev/{null,zero,urandom,random,tty}
access - Cgroups v2 (cpu, memory, pids)
- Networking
- Host networking
- slirp4netns
- Port forwarding
- Image management
- List/show images
- Pull images from registry
- Remove images
- Building images (Boxfile? Foxfile?)
- Volumes
- Global volumes
- Local volumes (
-v $(pwd):/workdir
) - tempfs mount
- Store foxboxes in a fixed place (e.g.
/var
or~/.foxbox
) - Run as daemon to simplify configs
- (maybe) Use OCI Image Format for images