Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
doos
Version: see VERSION (currently 0.1.3). Release history: CHANGELOG.md.
User-level containers in C++20: overlayfs over the host's /usr, /etc, /opt, user/mount/pid namespaces, networking through slirp4netns. No root at runtime.
doos list
doos get_or_create [--net slirp|host|none] NAME
doos attach [--net slirp|host|none] NAME [-- CMD...]
doos delete [--yes] NAME
Build: cmake -S . -B build && cmake --build build. Test: tests/run.sh.
Requirements: Linux >= 5.11, slirp4netns for the default network mode. On Ubuntu 24.04+ install the AppArmor profile once:
sudo cp apparmor/doos /etc/apparmor.d/doos && sudo apparmor_parser -r /etc/apparmor.d/doos
See SPEC.md (behavior, limits) and docs/RESEARCH.md (what works, measurements, known gaps).
Usage examples
doos get_or_create dev # created dev
doos attach dev # interactive shell as root inside
doos attach dev -- apt --version # run one command
doos attach --net none sandbox -- sh # no network at all
doos list
doos delete dev # dry run: shows what would go
doos delete --yes dev # really deletes
Container writes to /usr, /etc, /opt stay in the container (copy-on-write);
/root and /var are private and persistent. /tmp is memory-backed and lost on exit.
A container is running while its first attach command is alive; more attach calls
join it. Data persists until delete --yes.
Current limits you will hit
Tools run fine (curl, git, gcc, python3, pip, ping all verified). Package management does
not: apt-get update needs a seeded /var and -o APT::Sandbox::User=root, and
apt-get install cannot finish configuring packages because host-root-owned files are
unwritable and unchownable inside. Details, measurements and the fix are in
docs/RESEARCH.md (G7, "Field trial").
Configuration
| Variable | Meaning |
|---|---|
DOOS_HOME |
State directory (default ~/.local/share/doos). No , or : allowed. |
XDG_DATA_HOME |
Used as $XDG_DATA_HOME/doos when DOOS_HOME is unset. |
Troubleshooting
| Message | Cause and fix |
|---|---|
write /proc/<pid>/uid_map ... blocked or mount ...: Permission denied |
AppArmor restricts user namespaces. Install apparmor/doos (command above). |
slirp4netns failed to start |
Install slirp4netns, or use --net none / --net host. |
state path must not contain ',' or ':' |
Set DOOS_HOME to a plain path. |
container 'x' is running on delete |
Exit the attached command first. |
container limit reached (64) |
Delete one first. |
Safety summary
Host files are never written: system dirs are reached only through overlayfs. Host
/home, /sys and host loopback are not reachable in the default mode. --net host
removes network isolation and is opt-in. Known gaps (no cgroups, readable host /etc)
are listed with researched solutions (G1 to G6, not implemented) in docs/RESEARCH.md.
Project docs
| File | Content |
|---|---|
SPEC.md |
Behavior contract and limits |
docs/ARCHITECTURE.md |
Code map and flows |
docs/RESEARCH.md |
What works unprivileged, measurements, gaps |
AGENTS.md |
Rules for AI agents, release workflow |
CHANGELOG.md |
Release history |