Remora
Remora is a daemonless Linux container runtime written in Rust. It can run a single container or orchestrate a multi-service stack — and its primary interface is a Lisp scripting language, not YAML.
The .reml scripting layer lets you express things that declarative config cannot:
run a migration before the app starts, wait for a port to be ready, react to
failure with cleanup logic, or build a dependency graph that executes in parallel.
A runtime that is programmable from first principles.
Remora is also an embeddable Rust library, making it possible to add container isolation directly to your own programs without spawning a daemon or shelling out to Docker.
User Guide — full CLI reference, networking, storage, security, scripting, and more.
What makes it different
| Remora | Docker | runc | |
|---|---|---|---|
| Daemon required | ❌ | ✅ | ❌ |
| Library API | ✅ | ❌ | ❌ |
| Config language | Lisp (.reml) |
YAML | JSON |
| Imperative scripting | ✅ full language | ❌ | ❌ |
| Security-by-default | ✅ all containers | opt-in | opt-in |
| Rootless networking | ✅ pasta | ✅ | limited |
Security-by-default means every container gets seccomp-BPF filtering,
all capabilities dropped, no-new-privileges, masked kernel paths, and PID/UTS/IPC
namespace isolation — without any flags. Services that need specific capabilities
opt back in with :cap-add.
The .reml scripting interface
Remora's compose files are Lisp programs, not config schemas. A minimal stack:
But when you need more than ordering, the full language is available:
; Start the database and wait for it
; Run migrations — abort the whole deploy if they fail
; Start the app, clean up on any exit
The same interpreter supports a futures graph for parallel execution:
See docs/REML_EXECUTOR_MODEL.md for the full
scripting reference.
Features
Isolation
- Namespaces: UTS, Mount, IPC, Network, User, PID, Cgroup
- Filesystem: chroot, pivot_root, automatic /proc /sys /dev mounts
- Security defaults: seccomp-BPF + all capabilities dropped + no-new-privileges
- masked paths applied to every container unconditionally
Security
- Seccomp-BPF: Docker's default profile via pure-Rust
seccompiler - Capability management: all caps dropped by default;
:cap-addrestores specific ones - No-new-privileges:
PR_SET_NO_NEW_PRIVSblocks setuid/setgid escalation - Read-only rootfs:
MS_RDONLYremount makes the filesystem immutable - Masked paths:
/proc/kcore,/sys/firmware, and others hidden - Landlock LSM: per-path filesystem rules via Linux 5.13+ kernel interface
- Structural TOCTOU immunity: remora uses a single-threaded
pre_exechook and never re-execs itself — the architecture that drives the November 2025 runc CVE cluster (CVE-2025-31133, CVE-2025-52565, CVE-2025-52881) does not exist in remora. See docs/SECURITY.md for details.
Networking
- Loopback: isolated NET namespace,
loonly - Bridge: veth pair + named bridge, IPAM, DNS service discovery
- NAT: nftables MASQUERADE, reference-counted across containers
- Port mapping: TCP DNAT via nftables + userspace proxy for localhost
- Named networks: user-defined bridge networks with custom subnets
- Multi-network: attach containers to multiple networks simultaneously
- DNS service discovery: dual-backend (built-in daemon or dnsmasq), automatic container name resolution on bridge networks
- Pasta: full internet access without root via pasta
Resource Management
- rlimits: memory, CPU time, file descriptors, process count
- Cgroups v2: memory hard limit, CPU weight, CPU quota, PID limit
- Resource stats:
child.resource_stats()reads live cgroup counters
Filesystem
- Bind mounts:
with_bind_mount()(RW) andwith_bind_mount_ro()(RO) - tmpfs: writable scratch space inside a read-only rootfs
- Named volumes: persisted storage, scoped per compose project
- Overlay filesystem: copy-on-write layered rootfs via overlayfs
OCI Images
- Pull:
remora image pull alpine— anonymous pulls from any OCI registry - Run:
remora run alpine /bin/sh— multi-layer overlay, image config applied - Build:
remora build -t myapp:latest— Remfile (Dockerfile-compatible syntax) with multi-stage builds, ARG, ADD (URLs + archives),.remignore, build cache - Manage:
remora image ls/remora image rm
Multi-Service Orchestration
remora compose up/down/ps/logs: dependency-ordered service lifecycle- TCP readiness:
:ready-portpolling before dependent services start - Scoped resources: networks, volumes, and container names prefixed per project
- Lifecycle hooks:
on-readycallbacks between startup tiers
Other
- Interactive containers: PTY, SIGWINCH relay, terminal restore
remora exec: run a command inside a running container (namespace join + PTY)- OCI Runtime Spec:
create/start/state/kill/deletelifecycle - Rootless: pull, build, run, overlay, and pasta networking without root
Installation
Download a pre-built static binary from the Releases page (x86_64 and aarch64 Linux, statically linked musl), or build from source:
# Install to /usr/local/bin:
# Or via cargo:
Quick Start
Rootless (no sudo)
# Interactive shell with internet
Root (full feature set)
# Detached container with bridge networking
&&
Multi-service stack
# Declarative
# Imperative
Rust Library API
use ;
let mut child = new
.args
.with_chroot
.with_namespaces
.with_proc_mount
.with_seccomp_default
.drop_all_capabilities
.with_cgroup_memory
.spawn?;
child.wait?;
// Interactive shell
let session = new
.with_chroot
.with_namespaces
.with_proc_mount
.spawn_interactive?;
session.run?; // relays stdin/stdout, forwards SIGWINCH, restores terminal
See the CLI-to-API translation table in the user guide.
Testing
# Unit tests (no root required):
# or: cargo test --lib
# Integration tests (require root):
# or: sudo -E cargo test --test integration_tests
# E2E tests — exercises the full binary via BATS (require root + bats):
# or: sudo -E bats tests/e2e/hardening.bats tests/e2e/lifecycle.bats
The E2E suite verifies that remora compose up applies all four security
hardening defaults to every container it starts, and exercises the full
compose lifecycle (up / ps / down).
See docs/INTEGRATION_TESTS.md for documentation
of every integration test.
Architecture
Pre-exec hook order
- Parent — opens namespace files, compiles seccomp BPF, sets up bridge netns
- Fork
- Child pre_exec — unshare → UID/GID maps → setuid/setgid → chroot/pivot_root → mounts → capability drop → rlimits → setns → seccomp (must be last)
- exec — replace child with target program
Capability drop comes after all mount operations (masked paths, read-only rootfs)
because those mounts require CAP_SYS_ADMIN. Seccomp is last because setup
requires syscalls it would otherwise block.
Documentation
| File | Contents |
|---|---|
docs/USER_GUIDE.md |
CLI and API reference |
docs/REML_EXECUTOR_MODEL.md |
Lisp scripting: futures graph, run, then, parallel execution |
docs/INTEGRATION_TESTS.md |
Every integration test documented |
docs/DESIGN_PRINCIPLES.md |
Non-negotiable design principles |
docs/ROADMAP.md |
What's done and what's next |
docs/FEATURE_GAPS.md |
Gap analysis vs. Docker Desktop / Finch |
docs/RUNTIME_COMPARISON.md |
Full feature matrix vs runc/Docker |
docs/SECCOMP_DEEP_DIVE.md |
Seccomp-BPF implementation details |
docs/PTY_DEEP_DIVE.md |
PTY/interactive session design |
docs/CGROUPS.md |
Cgroups v1 vs v2 analysis |
docs/BUILD_ROOTFS.md |
How to build the Alpine rootfs |
CHANGELOG.md |
Version history and release notes |
Requirements
- Linux kernel 5.11+ recommended (rootless overlay with
userxattr) - Kernel 5.0+ works with root, or rootless with
fuse-overlayfsinstalled pasta(passt) for rootless networkingnft(nftables) for NAT and port mapping (root only)ip(iproute2) for bridge networking (root only)batsfor E2E tests (sudo pacman -S batsorsudo apt install bats)
License
See LICENSE file for details.