Development Environment (QEMU VM)
If you only have a laptop or a cloud VM — not a dedicated bare-metal server — but you still want to try Cube Sandbox or hack on it, you can run Cube Sandbox inside a disposable OpenCloudOS 9 virtual machine on your host.
The dev-env/ directory at the repository root scripts the whole flow: one-off image preparation, VM boot, and auto-login.
Three commands and you have a working Cube Sandbox playground.
Prerequisites
The scripts in this guide must run on one of the following hosts:
- WSL 2 on Windows (requires Windows 11 22H2+ with WSL nested virtualization enabled)
- A Linux physical machine
- A Linux VM with nested virtualization enabled (cloud VM or local VM both work)
In all three cases, the host must be able to use KVM — /dev/kvm must exist and be read/writable.
Cube Sandbox runs another layer of KVM MicroVMs inside the guest, so the host must support nested virtualization — otherwise the guest will have no usable /dev/kvm and sandbox creation will fail.
For detailed software dependencies and how to verify / enable nested KVM, see the "Host self-check" section further down.
Quick start
Clone the repository and enter dev-env/:
git clone https://github.com/tencentcloud/CubeSandbox.git
cd CubeSandbox/dev-envThree commands total. The first two run in one terminal, the third in a second terminal.
Step 1: Prepare the image (one-off)
./prepare_image.shThis downloads the official OpenCloudOS 9 qcow2 from the Tencent mirror and runs initialisation.
You only need to run this once per fresh image — or again after deleting the generated .workdir/ directory.
Step 2: Boot the VM
./run_vm.shThe QEMU serial console is attached to the current terminal. Press Ctrl+a then x to power the VM off.
Step 3: Log in (in a new terminal)
./login.shlogin.sh logs you into the VM as root — Cube Sandbox's installer requires root.
Install Cube Sandbox inside the VM
Once you are in the root shell, run the standard one-click installer:
curl -sL https://github.com/tencentcloud/CubeSandbox/raw/master/deploy/one-click/online-install.sh | bashUse the Tencent Cloud mirror from China
curl -sL https://cnb.cool/CubeSandbox/CubeSandbox/-/git/raw/master/deploy/one-click/online-install.sh | MIRROR=cn bashWhen the installer finishes, follow the regular Quick Start to create a template and run your first sandbox in the VM.
Everything below is supplementary material and troubleshooting — you can skip it if the happy path above worked.
When to use this
- You want a clean OpenCloudOS 9 environment to try Cube Sandbox.
- You only have a laptop or cloud VM with KVM and nested virtualization, not a physical server.
- You want to iterate on Cube Sandbox without polluting your host.
Not a production deployment method
This is explicitly a development / evaluation environment. For production, use Quick Start or Multi-Node Cluster on bare metal.
Host self-check
Software dependencies required on the host:
- Linux x86_64 with KVM enabled (
/dev/kvmexists) - Nested virtualization enabled
qemu-system-x86_64,qemu-img,curl,ssh,scp,setsid
Quick sanity check:
ls -l /dev/kvm
# Intel
cat /sys/module/kvm_intel/parameters/nested
# AMD
cat /sys/module/kvm_amd/parameters/nestedIf the nested parameter reads N or 0, enable it on the host before continuing. Example for Intel:
echo 'options kvm_intel nested=1' | sudo tee /etc/modprobe.d/kvm.conf
sudo modprobe -r kvm_intel && sudo modprobe kvm_intelHost ↔ guest port map
run_vm.sh configures these forwards automatically:
| Host | Guest | Purpose |
|---|---|---|
127.0.0.1:10022 | :22 | SSH into the dev VM |
127.0.0.1:13000 | :3000 | Cube Sandbox E2B-compatible API |
What prepare_image.sh does inside the guest
- Grow the root partition and filesystem to use the full 100 GB disk.
- Flip SELinux to
permissive(both at runtime and in/etc/selinux/config). Cube Sandbox's MySQL container bind-mounts/docker-entrypoint-initdb.dfrom the host; with enforcing SELinux andcontainer-selinuxpolicies in place, the container process gets denied and MySQL keeps restarting. - Ensure
/usr/local/{sbin,bin}are on the loginPATHand on sudo'ssecure_path, socubemastercliand friends work both from a login shell and fromsudo. - Install a welcome banner at
/etc/profile.d/cubesandbox-banner.sh, so every login shell greets you withWelcome to the Cube Sandbox development environment!.
Common overrides
All three scripts accept environment variables:
# Download + resize only, skip the in-guest auto-grow workflow.
AUTO_BOOT=0 ./prepare_image.sh
# Boot with more resources, or change the forwarded Cube API port.
VM_MEMORY_MB=16384 VM_CPUS=8 CUBE_API_PORT=23000 ./run_vm.sh
# Boot without requiring nested KVM (OS will boot but sandboxes won't run).
REQUIRE_NESTED_KVM=0 ./run_vm.sh
# Log in as the regular user instead of root.
LOGIN_AS_ROOT=0 ./login.shDefaults for run_vm.sh: 4 CPUs, 8192 MB RAM, SSH forwarded on 127.0.0.1:10022, Cube API forwarded on 127.0.0.1:13000 (guest :3000).
Reset / clean up
- To reset the VM state, stop any running
run_vm.sh, deletedev-env/.workdir/, then run./prepare_image.shagain. - The dev VM is disposable by design. You are expected to rebuild it whenever the installed state becomes unusable.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
No /dev/kvm inside the guest | Host does not have nested KVM enabled | Enable nested virtualization on the host and reboot the VM |
./login.sh cannot connect | VM not booted yet, or host port 10022 is busy | Confirm ./run_vm.sh is still running; or change SSH_PORT |
cube-sandbox-mysql keeps restarting with Permission denied | Guest SELinux is still enforcing | Re-run ./prepare_image.sh, or inside the guest: setenforce 0 && sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config && docker restart cube-sandbox-mysql |
df -h / inside the guest is still small | The auto-grow step did not complete | Inspect .workdir/qemu-serial.log, then scp internal/grow_rootfs.sh into the guest and run it manually |
Host port 13000 is already taken | Another service is bound to 13000 | Use CUBE_API_PORT=23000 ./run_vm.sh and update E2B_API_URL accordingly |
Directory layout
dev-env/
├── prepare_image.sh # one-off: download + resize + guest-side init
├── run_vm.sh # day-to-day: boot the VM
├── login.sh # day-to-day: SSH in and switch to root
├── internal/ # helper scripts invoked inside the guest
│ ├── grow_rootfs.sh
│ ├── setup_selinux.sh
│ ├── setup_path.sh
│ └── setup_banner.sh
├── README.md
└── README_zh.mdFor a short overview, see the dev-env/README.md in the repository.