Files
ecr/README.md
T
vhaudiquet 4f44af4449 feat: add --kernel flag for QEMU system emulation mode
Add --kernel <PATH> option to boot extracted rootfs in a QEMU virtual
machine instead of namespace/chroot mode. The rootfs is converted to an
ext4 disk image using mke2fs and booted with the provided kernel.
2026-06-16 19:16:34 +02:00

108 lines
3.6 KiB
Markdown

# ecr - ephemeral chroot
![](example.gif)
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] <DISTRO[:VERSION]> [-- 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 <PATH>` | Overlay-mount a directory read-only inside the chroot (default: current directory at `/root/<name>`) |
| `--bind-rw <PATH>` | Bind-mount a directory read-write at `/mnt/<name>` |
| `--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 <ARCH>` | Target architecture (`amd64`, `arm64`, `armhf`, `riscv64`, …) |
| `--kernel <PATH>` | Boot with QEMU system emulation using specified kernel |
| `-m, --memory <SIZE>` | Memory for QEMU VM (default: 2G, only with `--kernel`) |
## 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
# Boot with QEMU system emulation (requires qemu-system-<arch> and e2fsprogs)
ecr --kernel /boot/vmlinuz ubuntu
# Boot with custom memory
ecr --kernel /boot/vmlinuz --memory 4G alpine
```
## QEMU System Mode
When `--kernel` is specified, ecr boots the rootfs in a full QEMU virtual machine instead of using namespaces:
```sh
ecr --kernel /boot/vmlinuz alpine
```
This mode:
- Creates an ext4 disk image from the rootfs
- Boots QEMU with your kernel
- Provides full VM isolation
- Works for any architecture (no binfmt_misc needed)
Requirements:
- `qemu-system-<arch>` installed
- `e2fsprogs` for disk image creation
- Kernel with virtio support
## 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`