Qube

Qube Logo A lightweight Linux container runtime and container manager written in Go. Qube screenshot GitHub contributors GitHub CI Go Version Live Demo · Qube Hub · Documentation

Overview

Qube lets you run isolated Linux containers from a single Go binary. It provides a Docker-like workflow for pulling images, starting containers, exposing ports, mounting volumes, passing environment variables, snapshotting containers, and executing commands inside running workloads.

Qube can be used from:

Status: Qube is an educational and experimental container runtime. It demonstrates Linux namespaces, cgroups v2, filesystem isolation, daemon supervision, and image-based workflows. It is not a drop-in replacement for Docker or containerd.

Table of Contents

Features

Architecture

flowchart TD
    User["User"]

    subgraph ControlPlane["Host Control Plane"]
        CLI["Command-Line Interface"]
        Daemon["Background Daemon"]
        APIClient["API Client"]
    end

    subgraph Runtime["Qube Runtime"]
        Core["Container Runtime Engine"]
        API["Management API<br/><small>REST + WebSocket</small>"]
        Lifecycle["Container Lifecycle Tracker"]
    end

    subgraph Isolation["Isolated Container Environment"]
        Namespaces["Namespace Isolation"]
        Cgroups["Resource Limits<br/><small>cgroups v2</small>"]
        Filesystem["Isolated Root Filesystem"]
    end

    subgraph Storage["Storage Layer"]
        Images["Image Store<br/><small>Qube Hub tarballs</small>"]
        State["Container State Database"]
    end

    User --> CLI
    CLI --> Core
    CLI --> APIClient
    APIClient --> API
    API --> Core

    Daemon --> Lifecycle
    Daemon --> Core

    Core --> Namespaces
    Core --> Cgroups
    Core --> Filesystem
    Core --> Images

    Lifecycle --> State

Main components

Path Purpose
main.go Entrypoint and CLI dispatch
src/cli/ CLI commands such as run, list, stop, pull, eval, snapshot, info, and delete
src/daemon/ Background monitor that restarts containers and cleans orphaned state
src/api/ REST API on 127.0.0.1:3030 and WebSocket execution endpoint
src/core/container/ Runtime implementation: namespace setup, chroot, image extraction, filesystem operations, container startup
src/core/cgroup/ cgroups v2 CPU and memory resource controls
src/core/tracking/ Container tracking and persistence in /var/lib/Qube/containers.txt
src/config/ Global paths and test path overrides
src/testutil/ Helpers for remapping mutable paths in future tests
qube-apps/desktop/ Electron desktop app
qube-apps/hub/ Web hub for images and related workflows

System Requirements

Install common dependencies on Ubuntu/Debian:

sudo apt-get update
sudo apt-get install -y golang build-essential tar rsync make

Check cgroups v2:

mount | grep cgroup2

If cgroups v2 is unavailable, Qube can still run containers, but CPU and memory limits may not be applied.

Quick Start

git clone https://github.com/Voyrox/Qube
cd Qube
make install

Start the daemon:

sudo systemctl start qubed

Pull and run a container:

sudo qube pull Voyrox:nodejs:25.2.0
sudo qube run --image Voyrox:nodejs:25.2.0 --ports 3000 --cmd "npm install && npm start"

Inspect and stop the container:

sudo qube list
sudo qube info <container_name>
sudo qube stop <container_name>

Build Commands

Command Description
make build Build the qube binary
make install Build, install the binary, set permissions, and install the systemd service
make clean Remove build artifacts
make deps Download and tidy Go dependencies
make fmt Format Go code
make lint Run golangci-lint if installed
make test Run Go tests with coverage output
make daemon Build and run sudo ./qube daemon --debug
make dev Build with the Go race detector
make release Cross-compile Linux AMD64 and ARM64 binaries into bin/

CLI Usage

Run a container

sudo qube run --image <image> --cmd "<command>"

Examples:

# Run a Node.js service and expose port 3000
sudo qube run --image Voyrox:nodejs:25.2.0 --ports 3000 --cmd "node server.js"

# Run with environment variables
sudo qube run --image Voyrox:python:3.12.3 --env "DEBUG=true" --cmd "python app.py"

# Run with a volume mount
sudo qube run --image Voyrox:rust:1.92.0 --volume /host/path:/container/path --cmd "cargo run"

# Run with network isolation
sudo qube run --image Voyrox:nodejs:25.2.0 --ports 3000 --isolated --cmd "node server.js"

Container lifecycle commands

sudo qube daemon               # Start daemon manually
sudo qube run                  # Run container from flags or qube.yml
sudo qube list                 # List managed containers
sudo qube info <name>          # Show container metadata
sudo qube start <name>         # Start a stopped container
sudo qube stop <name>          # Stop a running container
sudo qube delete <name>        # Delete container state
sudo qube eval <name>          # Execute command in a container
sudo qube snapshot <name>      # Create a snapshot
sudo qube pull <image>         # Pull image from Qube Hub

Configuration

Qube supports a qube.yml file for repeatable container launches. The CLI supports both a container: top-level shape and a flatter legacy shape.

container:
  system: Voyrox:nodejs:25.2.0
  ports:
    - "3000"
  cmd:
    - npm install
    - node index.js
  isolated: false
  environment:
    API_KEY: "your-key-here"
    NODE_ENV: "development"
  volumes:
    - host_path: "/data"
      container_path: "/app/data"

Run it:

sudo qube run

Config fields

Field Description
system Image identifier to run
ports Ports to expose
cmd Command or command list executed inside the container
isolated Whether to enable stronger network isolation
environment Environment variables injected into the container
volumes Host-to-container volume mappings

Compatibility note: Some legacy structs preserve both environment and the misspelled enviroment field. Prefer environment in new config files.

REST and WebSocket API

The API is served locally on 127.0.0.1:3030.

Method Endpoint Purpose
GET /list List containers
POST /stop Stop a container
POST /start Start a container
POST /delete Delete a container
POST /info Get container details
GET /images List available images
GET /volumes List volumes
WS /eval/{name}/{action} Execute commands through WebSocket

Example API call:

curl http://127.0.0.1:3030/list

Example stop request:

curl -X POST http://127.0.0.1:3030/stop \
  -H "Content-Type: application/json" \
  -d '{"name":"Qube-example"}'

Runtime Internals

Isolation

Qube starts containers through a special init mode:

/proc/self/exe __container_init__

The runtime passes container setup through environment variables such as:

It then configures namespaces, filesystem isolation, and process startup.

cgroups v2

The cgroup layer controls memory and CPU where supported. Current defaults include:

Tracking

Container state is persisted in:

/var/lib/Qube/containers.txt

The tracking file is pipe-delimited:

name|pid|dir|cmds|timestamp|image|ports|isolated

Container IDs are generated as:

Qube-<6 alphanumeric chars>

unless a specific name is provided.

Daemon restart behavior

The daemon checks containers periodically and restarts managed containers when appropriate. Crash-loop protection pauses restart attempts after repeated failures.

Testing and Quality

Run the project checks:

make fmt
make test

Generate a coverage profile:

go test -v -covermode=count -coverprofile=coverage.out ./...

Current testing notes:

Recommended future test coverage:

Troubleshooting

permission denied

Qube requires root privileges for namespace, mount, chroot, and cgroup operations.

sudo qube <command>

cgroups are not applied

Check for cgroups v2:

mount | grep cgroup2

If there is no cgroup2 mount, containers can run without resource limits.

daemon is not running

sudo systemctl status qubed
sudo systemctl start qubed

Or run manually:

sudo qube daemon --debug

image does not exist locally

sudo qube pull Voyrox:nodejs:25.2.0

rebuild from a clean state

make clean
make deps
make build

Limitations

Security Notes

Qube is useful for learning and experimentation, but it should not be treated as a hardened sandbox. Running untrusted workloads as root can be dangerous. Review code paths, filesystem mounts, and image sources before running third-party workloads.

Contributing

  1. Fork the repository
  2. Create a feature branch:
git checkout -b feature/my-feature
  1. Format and test:
make fmt
make test
  1. Commit:
git commit -m "Add my feature"
  1. Push and open a pull request.

When adding runtime features, include:

License

See LICENSE.

Credits

Qube is maintained by Voyrox and contributors.