# doos specification Authoritative description of behavior and limits. Code constants live in `src/spec.hpp`; change both together. ## CLI | Command | Behavior | |---|---| | `doos list` | Table of NAME, STATE (running/stopped), NET, AGE. | | `doos get_or_create [--net M] NAME` | Creates the container if missing. Prints `created NAME` or `exists NAME`. | | `doos attach [--net M] NAME [-- CMD...]` | get_or_create, then run CMD (default `/bin/bash`, else `/bin/sh`). Starts the container if stopped, joins it if running. Exit code is the command's. | | `doos delete [--yes] NAME` | Dry run unless `--yes`. Refuses a running container. | `get-or-create` is accepted as an alias. Network mode `M` is fixed at creation: `slirp` (default), `host`, `none`. ## Limits (hard caps) | Item | Cap | |---|---| | Containers | 64 | | Name | `[a-z0-9][a-z0-9_-]{0,31}` | | Command arguments | 256 | | Open files inside | 4096 | | `/tmp`, `/run`, `/dev/shm` | 256m, 64m, 64m (tmpfs) | | slirp4netns ready wait | 5 s | | Lock wait | 5 s | | Delete recursion depth | 256 | ## State layout `$DOOS_HOME`, else `$XDG_DATA_HOME/doos`, else `~/.local/share/doos`. Path must not contain `,` or `:`. ``` containers/NAME/{meta,pid,lock,rootfs/,layers//{upper,work},private/{root,var}} ``` ## Container filesystem | Path | Source | |---|---| | `/usr /etc /opt` (and `/bin /sbin /lib /lib32 /lib64` when real dirs) | overlayfs, lower = host dir, upper = `layers//upper` | | `/bin /sbin /lib...` when host symlinks | same symlink recreated | | `/root /var` | persistent private dirs, no host data | | `/tmp /run /dev/shm` | tmpfs | | `/dev` | tmpfs + bound null zero full random urandom tty, new devpts instance | | `/proc` | own pid namespace; `sys sysrq-trigger irq bus fs` read-only; `kcore keys timer_list` masked | | `/sys`, `/home`, everything else on host | absent | ## Isolation User, mount, pid, uts, ipc namespaces always; network namespace unless `host`. Single-entry id map (container root = invoking user). `no_new_privs`, core dumps off. pid 1 is a reaping init that forwards SIGTERM/SIGINT/SIGHUP/SIGQUIT and kills the container when the command exits. Container lifetime = the first `attach` command; later attaches join via setns. ## Networking - `slirp`: private netns, `slirp4netns --configure --disable-host-loopback`, DNS 10.0.2.3, outbound only, host 127.0.0.1 unreachable. - `none`: private netns with loopback only. - `host`: shares the host network namespace (no isolation, explicit opt-in). ## Safety rules - `delete` is dry-run by default, scoped to `containers/NAME`, refuses running containers, never follows symlinks. - Invalid names, bad state paths and missing slirp4netns fail loudly. - A failed start kills the half-built container (no orphans).