원문 캡처 · github.com
원문 캡처 · github.com

vroot — 샌드박스 안의 루트 셸

vroot는 플래그 하나로 밀리초 만에 시작하는 격리된 단일 파일 Linux 개발 환경을 제공한다. 필요한 도구를 플래그로 지정해 임시 또는 지속형 루트 파일 시스템을 만들 수 있다.

vroot만 실행하면 배너와 빠른 시작 안내가 표시된다. vroot -base는 빈 Alpine Linux 루트 셸을, vroot -python은 Python이 설치된 루트 셸을 연다. vroot -node -python처럼 플래그를 조합할 수 있고, vroot -sqlite -python db는 db라는 이름의 지속형 샌드박스를 만든다. vroot -rust -- cargo build처럼 셸 대신 명령 하나만 실행할 수도 있다.

호스트의 파일은 -v로 공개하지 않는 한 샌드박스 안에서 보이지 않는다. 이름을 지정하지 않은 샌드박스는 종료하면 사라지고, 이름을 지정하면 유지된다.

AI 에이전트가 작동하는 도구 체인을 갖추는 데도 쓸 수 있다. 제작자는 데몬, 이미지 레지스트리, sudo, 빌드 대기열이 필요 없다고 설명한다. 에이전트용 동작 규약은 docs/AGENTS.md에 있다.

에이전트와 개발 환경에서의 사용

vroot는 필요한 자원을 즉시 제공하고 조정 부담을 줄이는 작업 방식에 맞춰 설계됐다. 제작자에 따르면 도구 체인은 플래그 하나로 지정하며 수십 밀리초 안에 시작한다. 따라서 에이전트는 깨지기 쉬운 환경을 재사용하는 대신 각 단계마다 새 환경을 만들 수 있다.

관리 명령에 --json을 붙이면 JSON 출력을 받을 수 있다. vroot build -python --json, vroot ls --json, vroot envs --json, vroot info NAME --json이 이에 해당한다. 표준 출력에는 JSON만 기록되고 로그는 표준 오류로 보내며, 종료 코드는 의미 있는 값을 반환한다.

동시에 여러 에이전트가 같은 환경을 요청하면 첫 프로세스가 이미지를 만들고 나머지는 기다린 뒤 "cached": true를 보고한다. 캐시 추출은 원자적으로 이뤄져 동시에 실행해도 서로의 파일을 손상시키지 않는다고 제작자는 설명한다.

vroot save NAME golden.vroot로 작업 상태를 파일 하나에 저장한 뒤, 그 이미지를 여러 이름의 샌드박스로 실행할 수 있다. 실패한 샌드박스는 버릴 수 있으며 저장된 이미지는 수정되지 않는다. 샌드박스 안에서는 실제 uid 0 권한을 얻지만, 호스트 파일 시스템과 프로세스는 기본적으로 보이지 않는다. 호스트 네트워크도 명시적으로 마운트하지 않는 한 노출되지 않는다.

이름 없는 샌드박스는 임시로 쓰이고, 이름이 있는 샌드박스는 지속된다. -offline으로 네트워크를 끌 수 있으며 vroot doctor로 호스트 설정을 사전 점검한다.

sh
$ vroot build -python --json
{"env":"/home/u/.local/share/vroot/envs/python-84d0423ed3.sqfs","cached":false}
$ vroot -python task1 -- pytest -q # exit code is pytest's
$ vroot save task1 task1.vroot && vroot task1.vroot retry -- pytest -q

에이전트용 출력 형식, 잠금, 분기 동작, 사용 규칙은 docs/AGENTS.md에 설명돼 있다.

주요 특징과 비교

vroot는 언어나 도구를 설치한 깨끗한 Linux 셸이 필요할 때 쓰는 경량 샌드박스이자 컨테이너 대안이다. 이미지를 직접 빌드하거나 데몬을 실행하지 않고 빠르게 시작할 수 있도록 만들어졌다.

  • 환경은 압축된 단일 이미지로 저장되고 쓰기 시 복사 방식으로 마운트된다. 제작자가 제시한 일반적인 콜드 스타트 시간은 수십 밀리초다. 셸 시작은 컨테이너 부팅이 아니라 마운트 후 실행하는 방식이다.
  • 호스트의 $HOME, 파일, 프로세스는 기본적으로 보이지 않는다. 샌드박스에는 자체 루트 파일 시스템, PID 네임스페이스, 호스트 이름, 네트워크가 있다. -offline을 지정하면 네트워크를 끌 수 있다.
  • 비특권 사용자 네임스페이스와 bubblewrap을 사용한다. 샌드박스 안에서는 uid 0과 전체 기능을 제공하지만, 데몬이나 setuid 헬퍼, 호스트의 루트 권한은 필요하지 않다.
  • -php -sqlite -git처럼 플래그를 조합해 하나의 환경에 도구를 함께 설치할 수 있다. 조합마다 별도로 캐시하고 다시 사용한다.
  • 환경을 한 번 만든 뒤 save로 변경 사항을 포함한 샌드박스를 휴대 가능한 .vroot 이미지 하나로 저장할 수 있다. vroot filetype install을 실행하면 데스크톱에서 해당 파일 형식을 등록할 수 있다.
  • 각 플래그는 짧은 텍스트 레시피다. 몇 줄을 추가해 언어나 도구를 확장할 수 있다. 자세한 내용은 docs/BUILDING.md를 참고하면 된다.
비교 항목vrootDocker / Podmanchrootproot전체 가상 머신
시작 시간약 10~50ms약 0.3~2초즉시약 0.1~1초수 초
루트 권한 / 데몬 필요 여부아니요 / 아니요아니요 / 예(또는 루트리스 설정)예아니요아니요
호스트 파일 시스템 숨김예예아니요일부예
내부에서 실제 uid 0 사용예예예아니요(가짜 권한)예
환경별 저장 방식파일 하나계층형 이미지와 컨테이너디렉터리디렉터리디스크 이미지
플래그로 도구 조합예Dockerfile / 실행 인수수동수동수동
적합한 용도루트 셸, 언어 샌드박스, 재현 가능한 개발 셸서비스, 이미지, 오케스트레이션레거시 시스템 관리에뮬레이션, 특이한 아키텍처완전한 격리

요구 사항과 설치

필요한 환경은 다음과 같다.

  • 비특권 사용자 네임스페이스가 활성화된 Linux. 최신 배포판에서는 기본으로 켜져 있으며 vroot doctor로 확인할 수 있다.
  • bubblewrap, util-linux의 unshare, squashfs-tools의 mksquashfs와 unsquashfs.
  • 기본 루트 파일 시스템을 처음 가져올 때만 필요한 curl 또는 wget.
  • Debian 베이스를 대상으로 하는 레시피 플래그를 사용할 때만 필요한 docker. 해당 플래그는 bun, clojure, groovy, julia, kotlin, scala, swift다.

배포판별 패키지 설치 명령은 다음과 같다.

sh
sudo apt install bubblewrap util-linux squashfs-tools curl
sh
sudo dnf install bubblewrap util-linux squashfs-tools curl
sh
sudo pacman -S bubblewrap util-linux squashfs-tools curl

설치 후 호스트 설정을 확인한다.

sh
vroot doctor

설치 스크립트는 sudo나 데몬 없이 실행할 수 있다.

sh
curl -fsSL https://raw.githubusercontent.com/gairxx/vroot/main/install.sh | sh

실행기는 ~/.local/bin/vroot에, 레시피 카탈로그는 ~/.local/lib/vroot에 설치된다. 설치 후 vroot doctor로 bubblewrap, 네임스페이스, squashfs 설정을 확인하고 vroot -python으로 Python이 있는 루트 셸을 열 수 있다.

명령을 복사할 수 있는 웹 페이지는 gairxx.github.io/vroot다. 설치 방법은 다음과 같다.

  • 한 줄 설치: curl -fsSL https://raw.githubusercontent.com/gairxx/vroot/main/install.sh | sh
  • 저장소를 복제한 뒤 설치: git clone https://github.com/gairxx/vroot && cd vroot && sh install.sh
  • 소스 아카이브: main.tar.gz을 내려받아 푼 뒤 sh install.sh 실행
  • 설치 경로 지정: curl -fsSL ... | sh -s -- --prefix /opt/vroot
  • 브랜치나 태그 지정: curl -fsSL ... | sh -s -- --version <branch-or-tag>
  • 제거: curl -fsSL ... | sh -s -- --uninstall

체크아웃한 저장소 안에서 install.sh를 실행하면 현재 작업 트리에서 설치하고, 그 밖의 위치에서 실행하면 tarball을 내려받는다. 어느 경우에도 빌드 단계는 없다. 제거해도 ~/.local/share/vroot에 있는 샌드박스와 이미지는 유지된다.

빠른 시작

sh
# Banner + quick-start help (no sandbox)
vroot

# A disposable root shell (blank Alpine)
vroot -base

# A root shell with a language
vroot -python
vroot -node
vroot -rust

# Compose as many tools as you like
vroot -php -sqlite -git

# Run a single command and exit
vroot -node -- node -e 'console.log(process.version)'

# A persistent sandbox you can come back to
vroot -python work
vroot work -- python3 -c 'print("still here")'

# Expose a host directory (read-write), keep everything else hidden
vroot -go -v ~/src:/src -- sh -c 'cd /src && go test ./...'

# Fully offline
vroot -python -offline

샌드박스 안에서는 루트 권한을 얻지만 호스트는 바뀌지 않는다고 제작자는 설명한다. 아래 예시에서는 id, hostname, /home 목록을 확인한다.

sh
$ vroot -python -- sh -c 'id; hostname; ls /home'
uid=0(root) gid=0(root)
vroot
ls: /home: No such file or directory

플래그와 옵션

각 플래그는 도구나 언어 하나를 지정한다. 원하는 환경에 맞춰 여러 개를 조합할 수 있다.

  • 언어 및 런타임: -python, -node, -deno, -bun, -php, -ruby, -perl, -lua, -r, -julia, -go, -rust, -zig, -nim, -crystal, -d, -swift, -haskell, -elixir, -erlang, -ocaml, -clojure, -groovy, -java, -kotlin, -scala, -dotnet, -fsharp
  • 컴파일 및 빌드 도구: -gcc, -clang, -cmake, -gfortran, -nasm
  • 데이터베이스 및 도구: -sqlite, -postgres, -mysql, -git, -openssh, -curl, -vim
  • 기본 환경: -base, -debian

-python3, -nodejs, -cargo, -golang 등의 별칭도 지원한다. 자세한 전체 목록은 docs/LANGUAGES.md 또는 vroot recipe list에서 확인할 수 있다.

실행 형식은 vroot [FLAGS] [NAME] [OPTIONS] [-- COMMAND]다. 주요 옵션은 다음과 같다.

  • -v SRC[:DST][:ro]: 호스트 경로를 공개한다. 기본은 읽기·쓰기이며 :ro를 붙이면 읽기 전용이다.
  • -offline: 네트워크를 차단하고 루프백만 허용한다.
  • -cwd DIR: 작업 디렉터리를 지정한다. 기본값은 /root다.
  • -env K=V: 환경 변수를 지정한다.
  • -name NAME: 지속형 샌드박스 이름을 지정한다.
  • -hostname H: 샌드박스 안의 호스트 이름을 지정한다. 기본값은 샌드박스 이름이다.
  • -clean: 빈 환경으로 시작한다.
  • -rm: 세션이 끝난 뒤 샌드박스를 삭제한다.
  • --json: build, ls, envs, info 명령에 기계가 읽을 수 있는 출력을 사용한다.

샌드박스와 환경 관리는 다음 명령으로 수행한다.

  • vroot ls: 샌드박스 목록을 표시한다.
  • vroot rm NAME... | --all: 지정한 샌드박스나 전체 샌드박스를 삭제한다.
  • vroot info NAME: 샌드박스 정보를 표시한다.
  • vroot save NAME [OUT.vroot]: 샌드박스를 .vroot 이미지 파일 하나로 묶는다.
  • vroot OUT.vroot: 저장된 이미지에서 샌드박스를 시작한다.
  • vroot filetype install: 운영체제에 .vroot 이미지 파일 형식을 등록한다.
  • vroot envs: 빌드한 환경 이미지 목록을 표시한다.
  • vroot prune: 캐시와 임시 파일을 지운다.
  • vroot recipe list|show|new|edit|path: 레시피를 관리한다.
  • vroot doctor: 호스트 설정을 점검한다.

작동 방식과 환경 확장

vroot는 다음 과정을 거쳐 환경을 준비하고 실행한다.

  • 레시피 확인: 플래그에 해당하는 레시피를 찾고 패키지, 설정 단계, 환경 변수, PATH, 검증 항목을 합친다.
  • 최초 빌드: 각 플래그 조합을 처음 사용할 때 envs/<flags>-<hash>.sqfs 형태의 단일 환경 이미지를 만든다. 최소 기본 루트 파일 시스템을 샌드박스 안에 채운 뒤 mksquashfs로 묶는다. 기본은 Alpine이며 glibc가 필요한 레시피는 Debian을 사용한다.
  • 실행: 세션마다 이미지를 캐시하거나 압축 해제한 뒤 overlayfs 마운트와 bubblewrap으로 실행한다. 이 과정에서 전체 기능을 가진 루트 셸, 격리된 네임스페이스, 쓰기 시 복사 방식의 파일 변경을 제공한다.

지속형 샌드박스의 변경 파일은 ~/.local/share/vroot/instances/<name>/upper에 저장된다. 따라서 save 명령으로 해당 상태를 휴대 가능한 이미지 파일 하나에 담을 수 있다.

text
                  ┌──────────── envs/python+sqlite-<hash>.sqfs ────────────┐                  │  read-only squashfs image (built once, cached)         │                  └───────────────────────┬───────────────────────────────┘                                          │ unsquashfs                      lowerdir ───────────┤                                          ▼   host $HOME ── overlayfs (COW) ──► merged root ── bubblewrap ──► uid 0 shell   (hidden)         upperdir (your writes)        namespaces: user, pid,                                                    uts, ipc, net, mount  

새 언어나 도구는 플래그 레시피를 추가해 확장한다. 제작자는 보통 몇 줄이면 충분하다고 설명한다.

text
name = mytool
provides = mytool
base = alpine
packages = mytool
verify = mytool --version
description = My tool

vroot recipe new mytool # create + edit, then:
vroot -mytool

실제 예시는 docs/BUILDING.md, 레시피 필드 설명은 docs/RECIPES.md에서 확인할 수 있다. 에이전트와 자동화 동작 규약은 docs/AGENTS.md, 전체 플래그 목록은 docs/LANGUAGES.md에 있다. 예제 레시피는 examples/에 공개돼 있다.

자주 묻는 질문

vroot는 Docker와 다르다. Docker는 데몬을 통해 OCI 이미지를 빌드하고 실행하며 서비스와 오케스트레이션에 적합하다. vroot는 단일 스크립트로 단일 파일의 쓰기 시 복사 이미지에서 격리된 루트 셸을 제공하며, 데몬이나 이미지 빌드 없이 빠르게 시작한다. 제작자는 vroot가 proot 또는 기능을 확장한 chroot에 더 가깝다고 설명한다.

호스트에서 루트 권한이나 sudo는 필요하지 않다. 실행에는 비특권 사용자 네임스페이스와 bubblewrap을 사용한다. 샌드박스 안에서는 uid 0과 전체 기능을 얻지만 사용자, PID, 마운트, UTS, IPC 네임스페이스로 격리된다. 호스트 파일 시스템은 기본적으로 보이지 않는다. 이는 호스트의 루트가 아니라 격리된 네임스페이스 안의 실제 루트 권한이다.

프로젝트 파일을 사용하려면 -v ~/src:/src처럼 명시적으로 공개한다. 요청하지 않은 파일은 공유되지 않는다.

환경은 ~/.local/share/vroot/ 아래의 envs/, cache/, instances/에 저장된다. $VROOT_HOME으로 위치를 바꿀 수 있다. 레시피는 ~/.config/vroot/recipes/에서 읽으며 $VROOT_CONFIG으로 경로를 바꿀 수 있다.

휴대 가능한 환경을 만들려면 vroot save NAME out.vroot를 실행하고 vroot out.vroot로 부팅한다. 내부 형식은 squashfs이며 .sqfs 확장자도 사용할 수 있다.

파일 관리자에서 vroot 이미지를 인식시키려면 vroot filetype install을 한 번 실행한다. 이 명령은 application/x-vroot-image MIME 형식과 데스크톱 처리기를 등록한다. *.vroot와 *.sqfs 확장자뿐 아니라 squashfs 매직 값도 감지하므로, 이미지 파일은 별도 형식으로 표시되고 vroot로 열린다. 등록을 취소하려면 vroot filetype uninstall, 설치 상태를 확인하려면 vroot filetype status를 실행한다.

기본값이 Alpine인 이유는 이미지가 작고 몇 초 만에 빌드되기 때문이다. glibc나 apt 전용 패키지가 필요한 레시피는 자동으로 Debian 베이스를 선택한다.

systemd가 없는 환경, 컨테이너 내부, WSL에서의 사용 가능 여부는 비특권 사용자 네임스페이스 지원에 달려 있다. vroot doctor로 확인할 수 있다.

AI 에이전트도 사용할 수 있으며 제작자는 이를 주요 사용 사례로 꼽는다. 관리 명령은 --json을 지원하고 표준 출력은 순수 JSON을 반환한다. 실행한 명령의 종료 코드가 전달되며, 같은 환경을 여러 프로세스가 동시에 빌드하면 작업을 직렬화한다. save로 샌드박스를 체크포인트한 뒤 저장 이미지를 새 이름으로 부팅해 분기할 수도 있다. 자세한 내용은 docs/AGENTS.md에 있다.

기본 라이선스는 MIT이며, 표기된 저작권 연도와 이름은 © 2026 gairxx다.