vhaudiquet d52310c0f4 feat: set unique hostname in QEMU VM mode
Generate hostname like "ecr-vm-<hex>" at boot time via kernel command
line, leaving initramfs cacheable. Set via echo to /etc/hostname and
hostname command before spawning shell.
2026-06-17 10:52:00 +02:00
2026-06-09 19:47:23 +02:00
2026-06-08 18:44:10 +02:00

ecr - ephemeral chroot

Instantly drop into a disposable Linux environment on your host machine.
No Docker daemon. No VM. No root. Just namespaces.

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

# 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>)
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:

ecr --kernel /boot/vmlinuz alpine

This mode:

  • Creates a gzipped CPIO initramfs 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
  • Kernel with serial console 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
S
Description
Ephemeral chroot into any distribution
Readme 663 KiB
Languages
Rust 100%