Skip to content

Repository files navigation


「 须臾水面明月出,沧江万顷琉璃寒 」

DOI Ask DeepWiki

Build release Run autotest

Warning

Most of the code is generated by human, maybe even neko.
If you found any issues, rewrite it with Claude.

WARNING

* Your warranty is void.
* I am not responsible for anything that may happen to your device by using this program.
* You do it at your own risk and take the responsibility upon yourself.
* This project is open source, you can make your own fork/rewrite but not to blame the author.
* The tail can never wag the cat.
* This program has no Super Cow Powers.

About:

 Not "Why not docker", but "When cannot docker".
 ruri is pronounced as lyoli, or you can call it [瑠璃/琉璃] (るり) in Chinese or Japanese as well.
 ruri is acronym to Lightweight, User-friendly Linux-container Implementation, as "better chroot", or "super chroot".
 ruri is a powerful container implementation that runs on almost any Linux device, even with incomplete kernel configurations or minimal storage space.

Features:

  • Aimed to be the most compatible "better chroot".
  • Default configuration works on almost every device with chroot support.
  • Simple usage, just ruri /path/to/rootfs [command...] to run a container.
  • CLI first, all features can be used in CLI, and config file is optional.
  • Supports chroot, unshare with pivot_root, environment/user/workdir setup, and more....
  • Umount & kill containers easily and safely.
  • Built-in binfmt_misc & QEMU for easy multi-arch containers.
  • Rootless containers, capability control, cgroups, seccomp profile, no new privileges, and more security features.
  • Flexible mount options, mount images/partitions, customizable mount flags, TMPFS and OVERLAY support.
  • Extensible, many feature flags can be enabled by --set-flag option.
  • Lifecycle tracking, --pid-file will record the whole lifecycle of container.
  • Statically linked binaries for many architectures.
  • Very small binary size (even <200k with upx), yet over 40 options.

ruri vs the alternatives:

Here's my honest and blunt bottom line (我给你最直白最不绕弯子的结论):

  • Use chroot when:
    • You are a developer and need a very stable implementation.
    • You just need a simple full-privilege environment (we often don't think chroot is container).
    • You are old-school and like to write the script yourself.
  • Use PRoot when:
    • You don't have root privileges.
    • You think that proot is more secure(even I can't agree that).
    • Maybe you don't care about performance.
  • Use bubblewrap when:
    • You're GNU/Linux user.
    • Your kernel supports it.
    • You need a stable and secure sandbox.
  • Use Docker/LXC when:
    • Your kernel supports it.
    • You need a industry-grade container solution.
    • You are geek, just like to do some cool things on android (yes, me too).
    • To be honest, they are not very stable on android.
  • Use ruri when:
    • You have only root privileges, without other kernel features.
    • Your device is not supported by Droidspaces, or you don't want to flash a custom kernel.
    • You just want to run some headless containers like some docker-images.
    • You are GNU/Linux user and just need a better chroot.
    • You are writing some custom CI/CD scripts *(Maybe you need to lock the source to a specific commit).
    • (Maybe) You are learning Linux container implementation and want to see how it works.
  • Use Droidspaces when:
    • Your kernel supports it.
    • Your device supports GKI and building/flashing a custom kernel is easy.
    • You need better init support, especially systemd.
    • You need better GUI support and Android-specific optimizations.
    • You need network isolation.
    • You need hardware access for containers.
    • You need better support for cgroups.
    • You don't want to be ruri's tester TwT

Here's the thing (我直接给你结论):

Android
├── No root
│   └── PRoot
│
└── Root
    │
    ├── Limited kernel features
    │   └── ruri
    │
    └── Namespaces + cgroups support
        │
        ├── Standard Linux container
        │   └── Docker/LXC
        │
        └── Android-optimized container
            │
            ├── CLI/headless
            │   └── ruri
            │
            └── GUI/systemd/hardware
                └── Droidspaces

As ruri is still in development, and we don't have many users yet, when you have any issues, please report, and we'll be happy to get your feedback :>
So, let's #MakeRuriGreatAgain

AVF, when?

ruri is not a vm tool, but you can just use it as super chroot to enter your target rootfs image, this is very useful when building/repairing your rootfs images.

# ./ruri -m LOOP::p2::/data/local/tmp/test.img / --set-flag new_tty ../vm
/ # ls
bin         home        media       proc        sbin        tmp
dev         lib         mnt         root        srv         usr
etc         lost+found  opt         run         sys         var
/ #

(LOOP::p2:: means the second partition of the loop image).

FULL USAGE:

See USAGE to explore all features of ruri.

FULL USAGE:

See USAGE to explore all features of ruri.

FULL USAGE:

See USAGE to explore all features of ruri.

NOTE:

The full usage is too long, so maybe you need to throw it to LLMs and let them explain it to you. See Asking LLM for how to ask LLM about ruri.

FAQ

FAQ

Container Security

See Enhance Container Security.

Seccomp profile:

After DirtyFrag and CopyFail, seccomp is more and more important for container security.
Our default seccomp profile is now ready, and will keep tracking the latest vulnerabilities.
You can enable it by using --enable-seccomp option. And if you have any suggestions/issues for the seccomp profile, please report.
NOTE: default seccomp profile blocks personality() syscall. And it will break debian reprotest, box86/wine and some other software. You can use --set-flag allow_personality to allow it.
We also kanged moby's seccomp profile, you can use --enable-seccomp-whitelist option to enable it.
For GhostLock, we have a --set-flag ban_futex_pi option to block futex_pi syscall, but it will break many software, so use it with caution.
But for vulnerabilities like bad-epoll (CVE-2026-46242), as epoll() is too important for linux, we can do nothing for it, you have to patch your kernel or use gvisor/kvm to avoid it.

About cwte:

I just have to find a way to zip seccomp profile code, so I made a tail :< mark for it, and I call it "cwte".
See cwte for more details about it.
Anyway, I have a 1853->1210 lines zip in seccomp.ce, for 34% smaller code size, and, as it's implimented in a special rule, the generated code is zero-diff than before.

Security Reporting:

Considering the security issues of chroot, ruri will drop CAP_SYS_CHROOT by default now
If you got any issues with this, please report.
In newest code, ruri will also do setgroups() for root user in container to avoid permission issues on some devices, If you'd like to disable it, please use --no-setgroups option.
See SECURITY.md.

The enhanced version

rurima was planned to be the ruri manager, but since it now has a full integration of ruri, you can use it as an enhanced version of ruri.

Terms of Use:

See TERMS_OF_USE.md

For Android user:

You need to root your phone first, ruri supports to run with root on Android devices.

Backward compatibility:

We promise that ruri has backward compatibility of cli usage and config file since v3.9.0, you can keep updated to the newest version. Any breaking changes will not be introduced to v3.9.x

Bug reporting

If you think something does not work as expected, please open a new isssue

Asking LLM:

See Asking LLM for how to ask LLM about ruri.

Get ruri

You can get ruri binary (statically linked) for arm64, armv7, armhf, riscv64, i386, loong64, s390x, ppc64le and x86_64 devices in Release. Or you can run the following command to download ruri automatically

. <(curl -sL https://get.ruri.zip/ruri)

This will automatically download ruri binary to ./ruri.

Quick start(with rurima)

Download and unpack a rootfs

. <(curl -sL https://get.ruri.zip/rurima)
./rurima lxc pull -o alpine -v edge -s /tmp/alpine

Then

sudo ruri /tmp/alpine

Setup dns:

In container:

rm test/etc/resolv.conf
echo nameserver 1.1.1.1|tee test/etc/resolv.conf

For unshare container

sudo ruri -u /tmp/alpine

Very simple as you can see. For command line examples, please see ruri -H.

Example Usage

# Run chroot container
  sudo ruri /tmp/alpine

# Very simple as you can see.

# About the capabilities
# Run privileged chroot container
  sudo ruri -p /tmp/alpine

# If you want to run privileged chroot container,
# but you don't want to give the container cap_sys_chroot privileges
  sudo ruri -p -d cap_sys_chroot /tmp/alpine

# If you want to run chroot container with common privileges,
# but you want cap_sys_admin to be kept
  sudo ruri -k cap_sys_admin /tmp/alpine

# About unshare
# Unshare container's capability options are same with chroot.
# Run unshare container
  sudo ruri -u /tmp/alpine

# Finally, umount the container
  sudo ruri -U /tmp/alpine

Behavior of rurienv

After initing the container, ruri will create a file /.rurienv by default, this config can unify container config, but it will also cover some of the command-line args, you can use --no-rurienv to disable it, or see rurienv.md to see its behavior. You might cannot remove this file unless you run chattr -i .rurienv, but don't worry, after umounting conainer by ruri -U, this config file will be removed automatically. If you want to change the container config, just use -U to umount it and re-run the container.

Build Manually

Ruri provides statically linked binary, but if you want to build it yourself, see Build.

Integration

ruri is ready to integrate into other projects, with the MIT License, it is compatiblte to be redistribute with almost all license, or commercial/closed source. An example is ruri's own build action , it runs containers for 9 different architectures to build itself, that shows its broad application prospects. Another example is rurima, I made ruri built-in for it, so it can be run as a subcommand. See Integration for a guide to integrate ruri into your projects.

Network isolation, when?

Never. You need a netns wrapper, or use --pid-file with empty_net_ns and wait_before_exec flag to setup the empty netns by another process, but ruri will not do it for you, as it can and should surely be decoupled from ruri.

Performance

On Macbook Air M4, orbstack, fedora 43:

[moe-hacker@fedora ruri]$ sudo /usr/bin/time -f "Time: %es\nMax memory: %M KB"  ./ruri -u ../ubuntu/ echo hello ruri
hello ruri
Time: 0.00s
Max memory: 5936 KB
[moe-hacker@fedora ruri]$ sudo /usr/bin/time -f "Time: %es\nMax memory: %M KB" echo hello ruri
hello ruri
Time: 0.00s
Max memory: 1516 KB

On Oneplus Ace 5 Ultra, Android 16:

~/ruri $ sudo $PREFIX/bin/time -f "Time: %es\nMax memory: %M KB" ./ruri --unshare --set-flag no_ipc_ns --set-flag no_pid_ns ../test echo hello ruri
hello ruri
Time: 0.02s
Max memory: 4396 KB
~/ruri $ sudo $PREFIX/bin/time -f "Time: %es\nMax memory: %M KB" echo hello ruri
hello ruri
Time: 0.01s
Max memory: 6572 KB

And even, on Pixel Watch 2, Android 17:

~ $ sudo $PREFIX/bin/time -f "Time: %es\nMax memory: %M KB" ./ruri -u --set-flag no_ipc_ns --set-flag no_pid_ns ./alpine echo hello ruri
hello ruri
Time: 0.04s
Max memory: 1340 KB
~ $ sudo $PREFIX/bin/time -f "Time: %es\nMax memory: %M KB" echo hello ruri
hello ruri
Time: 0.03s
Max memory: 4576 KB

Anyway, seems that my compiler and CPU is much more clever than me, as ruri doesn't have any optimization for performance in fact.

Binary size(amd64)

ruri crun %
(noupx) 454K 3.0M -84.9%
(withupx) 147K 1.3M -88.7%

Alphabet coverage

Alphabet ruri used %
52 47 90%

License

License of code

  • Licensed under the MIT License
  • Copyright (c) 2022-2025 Moe-hacker

License of clang-format config file

  • GPL-2.0

Also Thanks to:

  • moby, especially moby/profiles for the seccomp profile.
  • docker, for default container configuration and many other inspirations.
  • Droidspaces, for some environment/target-specific setups.

「 咲誇る花 美しく、

散り行く運命 知りながら、

僅かな時の彩を 」

(>_×)

About

A zipped Linux container runtime that zips (Lightweight User-friendly Linux-container Implementation)

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

216 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages