diff --git a/README.md b/README.md index 049d935..2cb1986 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,80 @@ # ecr - ephemeral chroot + + +Instantly drop into a disposable Linux environment on your host machine. +No Docker daemon. No VM. No root. Just namespaces. + +```sh +ecr debian # interactive Debian shell +ecr alpine:3.23 # specific Alpine version +ecr ubuntu:noble # Ubuntu by codename +ecr fedora # any Docker Hub image +``` + +## How it works + +`ecr` pulls a root filesystem (Alpine/Ubuntu direct from their CDNs; everything else from Docker Hub), extracts it into a temporary directory, and execs a shell inside a user + mount + PID + UTS namespace. The process tree is isolated, the rootfs is discarded on exit, and your host is never touched. + +## Usage + +``` +ecr [OPTIONS] [-- COMMAND...] +``` + +| Argument | Description | +|---|---| +| `ubuntu`, `alpine`, `debian`, `fedora`, … | Distribution to enter | +| `:version` | Optional version tag — codename, number, or `latest` / `lts` / `edge` | +| `-- cmd arg…` | Run a command instead of an interactive shell | + +### Options + +| Flag | Description | +|---|---| +| `--bind ` | Overlay-mount a directory read-only inside the chroot (default: current directory at `/root/`) | +| `--bind-rw ` | Bind-mount a directory read-write at `/mnt/` | +| `--no-bind` | Skip all directory mounts | +| `--no-cache` | Force a fresh download, bypassing the cache | +| `-v, --verbose` | Print diagnostic output (URLs, layer info, extraction steps) | +| `-a, --arch ` | Target architecture (`amd64`, `arm64`, `armhf`, `riscv64`, …) | + +## Examples + +```sh +# Quick shell in the latest Debian +ecr debian + +# Run a one-shot command +ecr alpine -- sh -c 'apk add curl && curl -s https://example.com' + +# Work on your project inside Ubuntu — changes are visible on the host +ecr ubuntu --bind-rw ~/projects/myapp + +# Native-compile for ARM64 through emulation (requires QEMU binfmt_misc) +ecr --arch arm64 alpine -- uname -m + +# Always pull a fresh image +ecr --no-cache fedora +``` + +## Supported distributions + +| Name | Source | Version examples | +|---|---|---| +| `alpine` | Alpine CDN | `latest`, `stable`, `edge`, `3.23`, `3.22` | +| `ubuntu` | Ubuntu CDN | `latest`, `lts`, `noble`, `24.04` | +| `debian` `fedora` `arch` `gentoo` | Docker Hub | `latest`, any tag | +| Any Docker Hub / OCI image | Registry | `org/image:tag`, `ghcr.io/…`, `localhost:5000/…` | + +## Cache + +Downloaded images are cached in `~/.cache/ecr/`. For `latest` OCI tags the registry manifest digest is checked on each run — the image is only re-downloaded when it has actually changed. Use `--no-cache` to force a fresh pull regardless. + +## Requirements + +- Linux kernel ≥ 5.1 +- Unprivileged user namespaces enabled (`/proc/sys/kernel/unprivileged_userns_clone` = 1 on some distros) +- `newuidmap` / `newgidmap` in `$PATH` +- An entry in `/etc/subuid` and `/etc/subgid` for your user +- For foreign-arch: QEMU user-mode emulation registered with `binfmt_misc`