CLI Reference

Table of contents

  1. Global Flags
  2. VM Commands
    1. uni run
    2. uni ps
    3. uni status
    4. uni stats
    5. uni logs
    6. uni inspect
    7. uni stop
    8. uni rm
    9. uni cp
    10. uni exec
  3. Image Commands
    1. uni build
    2. uni images
    3. uni rmi
    4. uni push
    5. uni pull
    6. uni search
    7. uni sign
    8. uni verify
  4. Package Commands
    1. uni pkg list
    2. uni pkg search
    3. uni pkg get
    4. uni pkg remove
    5. uni pkg create
    6. uni pkg from-docker
    7. uni pkg push
  5. Volume Commands
    1. uni volume create
    2. uni volume ls
    3. uni volume inspect
    4. uni volume rm
  6. Network and DNS Commands
    1. uni network create
    2. uni dns resolve
    3. uni dns list
  7. Cluster Commands
    1. uni node ls
  8. Kernel Commands
    1. uni kernel check
    2. uni kernel update
    3. uni kernel list
    4. uni kernel use
  9. Upgrade Commands
    1. uni upgrade
    2. uni upgrade check
    3. uni upgrade list
  10. Compose Commands
    1. uni compose up
    2. uni compose down
    3. uni compose ps
    4. uni compose logs
  11. VM States
  12. Daemon Flags
    1. Observability Endpoints
    2. Dashboard
    3. VM Runtime Stats

Global Flags

Every uni command accepts these flags:

Flag Default Description
--socket /var/run/unid.sock (Linux) / %TEMP%\unid.sock (Windows) Path to the unid Unix socket
--store ~/.uni/images Local image store directory
--output table Output format: table or json

VM Commands

uni run

Create and immediately start a unikernel VM.

uni run <image> [flags]

<image> can be:

  • A file path: ./myapp.img — path to a pre-built bootable disk image
  • A name:tag reference: hello:latest — looked up in the local image store

Note: uni run requires a bootable disk image, not a raw ELF binary. To package a binary into an image first run uni build --name <name> <binary>, then uni run <name>:latest.

Flags:

Flag Default Description
--memory 256M VM memory (e.g. 256M, 1G, 4G)
--cpus 1 Number of virtual CPUs
-p, --port Publish port(s): host:guest[/tcp\|udp] (repeatable)
-e, --env Set environment variable KEY=VALUE (repeatable)
--env-file Read environment variables from file (one KEY=VALUE per line)
--name Assign a human-readable name to the VM instance
--rm false Automatically remove the VM when it stops
-v, --volume Mount a named volume: name:guestpath[:ro] (repeatable)
--attach false Attach to VM serial console (blocks until VM stops)
-d, --detach true Run VM in the background (overridden by --attach)
--ip Static IP address, configured in the guest via fw_cfg (requires --network)
--network Managed network name created by uni network create
--health-check Health check probe: tcp:PORT or http:PORT:/path
--restart Restart policy: never, on-failure, or always[:max-retries]
--verify off Image signature verification: off, warn, enforce
--cpu-shares 0 cgroup v2 CPU weight (1–10000, 0=no limit, Linux only)
--memory-max cgroup v2 memory hard limit (e.g. 512M, 1G; Linux only)
--disk-iops 0 Disk I/O throttle: max IOPS for boot disk (0=no limit)
--disk-bps Disk I/O throttle: max bytes/sec for boot disk (e.g. 10M; 0=no limit)

Examples:

# Run from a pre-built disk image file
uni run ./myapp.img --memory 512M --cpus 2

# Run a built image by name
uni run myapp:latest

# Expose port 8080 on the host → port 80 inside the VM
uni run nginx:latest -p 8080:80

# Multiple ports and UDP
uni run myapp:latest -p 8080:80 -p 5353:53/udp

# Pass environment variables
uni run myapp:latest -e NODE_ENV=production -e PORT=3000

# Load env vars from a file
uni run myapp:latest --env-file .env

# Mount a named volume (create first with 'uni volume create')
uni run myapp:latest -v data:/var/data

# Read-only volume mount
uni run myapp:latest -v config:/etc/app:ro

# Named instance, auto-remove on exit
uni run hello:latest --name web --rm

# Attach to serial console (blocks until VM exits)
uni run hello:latest --attach

# Attach with a named instance and port
uni run myapp:latest --name api --attach -p 8080:8080

# Run on a managed network with auto-IP allocation
uni network create app
uni run myapp:latest --network app -p 8080:80

# Run on a managed network with explicit static IP
uni run myapp:latest --network app --ip 10.100.0.10 -p 8080:80

# Run with a health check (TCP probe on port 8080)
uni run myapp:latest --health-check tcp:8080

# Run with an HTTP health check
uni run myapp:latest --health-check http:8080:/healthz

# Restart automatically on failure (up to 5 times)
uni run myapp:latest --restart on-failure:5

# Always restart (unlimited retries)
uni run myapp:latest --restart always

# Output the VM ID for scripting
ID=$(uni run hello:latest --name api)
echo "Started VM: $ID"

Output:

a3f8c2d1-7b4e-4a1f-8c2d-1a2b3c4d5e6f

With --attach, the command blocks and streams the VM’s serial console output to stdout until the VM stops. No VM ID is printed in attach mode.


uni ps

List all registered VMs with health status.

uni ps

Examples:

uni ps
# ID                                    NAME     STATE    HEALTH     IMAGE
# a3f8c2d1-7b4e-4a1f-8c2d-1a2b3c4d5e6f  web      running  healthy    hello:latest
# b4e9d3e2-8c5f-5b2g-9d3e-2b3c4d5e6f7a  -        stopped  unknown    api:v2

# JSON output
uni --output json ps

JSON output:

[
  {
    "id": "a3f8c2d1-7b4e-4a1f-8c2d-1a2b3c4d5e6f",
    "state": "running",
    "name": "web",
    "health": "healthy",
    "image": "hello:latest"
  }
]

uni status

Show a summary of the daemon and all VMs, including health and restart information.

uni status

Examples:

uni status
# Total:      3
# Running:    2
# Stopped:    1
# Healthy:    1
# Unhealthy:  0
#
# ID                                    NAME     STATE    HEALTH     RESTARTS  IMAGE
# a3f8c2d1-7b4e-4a1f-8c2d-1a2b3c4d5e6f  web      running  healthy    0         hello:latest
# b4e9d3e2-8c5f-5b2g-9d3e-2b3c4d5e6f7a  api      running  starting   1         api:v2
# c5f0a4b3-9d6e-4c2f-a1b3-5d6e7f8a9b0c  -        stopped  -          0         worker:latest

# JSON output
uni --output json status

uni stats

Show resource usage for a single VM: CPU percentage, memory, and network I/O.

uni stats <id> [flags]

Flags:

Flag Default Description
-w, --watch false Continuously watch stats (refresh every interval)
-i, --interval 2s Watch interval (e.g. 1s, 5s)

Examples:

# Single snapshot
uni stats a3f8c2d1
# ID        a3f8c2d1-7b4e-4a1f-8c2d-1a2b3c4d5e6f
# State     running
# CPU       12.5%
# Memory    256.0 MiB
# Net RX    1.5 KiB
# Net TX    3.2 KiB
# Source    procfs

# Continuous watch (refresh every 2 seconds)
uni stats a3f8c2d1 --watch

# Custom watch interval
uni stats a3f8c2d1 --watch --interval 5s

# JSON output
uni stats a3f8c2d1 --output json

On non-Linux platforms, CPU and memory stats fall back to a fallback source with zero values. Full procfs-based stats are available only on Linux where the QEMU process /proc entries are accessible.


uni logs

Print captured serial console output (stdout + stderr) for a VM.

uni logs <id>

Example:

uni logs a3f8c2d1
# Hello from unikernel!
# tick 1
# tick 2

Logs are buffered in memory by unid. They are lost when the daemon restarts. For real-time streaming, use uni run --attach instead, which blocks and streams the serial console output directly to your terminal as the VM runs.


uni inspect

Display full details for a VM as JSON.

uni inspect <id>

Example:

uni inspect a3f8c2d1
{
  "id": "a3f8c2d1-7b4e-4a1f-8c2d-1a2b3c4d5e6f",
  "state": "running",
  "image": "hello:latest",
  "name": "web",
  "memory": "256M",
  "cpus": 1,
  "ports": [
    {"host_port": 8080, "guest_port": 80, "protocol": "tcp"}
  ],
  "env": ["NODE_ENV=production", "PORT=3000"],
  "volumes": [
    {"disk_path": "/home/user/.uni/volumes/data/disk.img", "guest_path": "/var/data", "read_only": false}
  ],
  "created_at": "2026-04-19T10:00:00Z",
  "started_at": "2026-04-19T10:00:01Z"
}

uni stop

Gracefully stop a running VM.

uni stop <id> [--force]

Shutdown sequence (without --force):

  1. Send SIGTERM to the QEMU process
  2. Wait up to 30 seconds for the VM to exit cleanly
  3. Send SIGKILL if still running after the grace period
Flag Default Description
--force false Skip grace period, send SIGKILL immediately

Examples:

# Graceful shutdown
uni stop a3f8c2d1

# Immediate kill
uni stop --force a3f8c2d1

uni rm

Remove a stopped VM from the registry.

uni rm <id>

The VM must be in stopped state. Run uni stop <id> first.

Example:

uni stop a3f8c2d1
uni rm a3f8c2d1

uni cp

Copy files to or from a stopped VM disk image. The dump and mkfs tools are downloaded automatically on first use from the kernel release.

uni cp <src> <dst>

One operand must be a VM reference in the form id:path, the other a local file path. Copying to a VM rebuilds the disk image with the new file included.

Examples:

# Copy a file from a stopped VM to the host
uni cp myvm:/etc/config.json ./config.json
# copied myvm:/etc/config.json → ./config.json

# Copy a file from the host into a stopped VM
uni cp ./local.conf myvm:/etc/config.json
# copied ./local.conf → myvm:/etc/config.json

# Copy from a VM identified by prefix
uni cp a3f8:/var/log/app.log ./app.log

uni exec

Send a signal to a running VM process.

uni exec <id> --signal <SIG>
Flag Default Description
--signal SIGTERM Signal name (e.g. SIGTERM, SIGHUP) or number (e.g. 15)

Examples:

# Reload configuration (if the app handles SIGHUP)
uni exec a3f8c2d1 --signal SIGHUP

# Send signal by number
uni exec a3f8c2d1 --signal 1

Supported signal names: SIGTERM, SIGINT, SIGKILL, SIGHUP, SIGQUIT, SIGUSR1, SIGUSR2


Image Commands

uni build

Build a unikernel image from a static ELF binary or a source directory.

uni build <path> [flags]

<path> can be:

  • A file path: ./hello — path to a pre-compiled static ELF binary (legacy mode)
  • A directory: . — build from source using a language driver (requires --lang or auto-detection)

When <path> is a directory, uni build detects the language from project markers (go.mod, package.json, etc.) or uses --lang explicitly, compiles the project, and packages the result into a unikernel image.

Flag Default Description
--name Binary/directory filename Image name
--tag latest Image tag
--memory 256M Default VM memory baked into the image
--cpus 1 Default CPU count baked into the image
--mkfs (auto-downloaded to ~/.uni/tools/mkfs) Path to Nanos mkfs binary — overrides auto-download (env: UNI_MKFS)
-U, --update-kernel false Auto-approve kernel update if one is available (skips the [y/N] prompt)
--pkg Include package in the image (repeatable). Downloads, extracts, and includes the package files
--lang (auto-detect) Build from source directory with language driver (go, node, python, rust)
--platform (native) Target platform for cross-compilation (e.g. linux/amd64, linux/arm64)

If the kernel tools are already cached and a newer kernel version is available, uni build will prompt before proceeding:

⚠  New kernel version available: v0.1.1 (installed: v0.1.0)
Update kernel before building? [y/N]

Examples:

# Basic build
uni build ./hello

# Custom name and tag
uni build ./myapi --name api --tag v1.2.0

# With resource defaults
uni build ./api --name api --tag latest --memory 512M --cpus 2

# Include a runtime package
uni build ./myapp --name myapp --pkg node:20

# Include multiple packages
uni build ./myapp --name myapp --pkg node:20 --pkg redis:7

# Build from source directory (Go project)
uni build --lang go .

# Build from source directory (auto-detect language)
uni build .

# Cross-compile for ARM64
uni build --lang go --platform linux/arm64 .

# Build with unikernel.toml config
uni build .

Language Drivers:

Language Detect Build Notes
go go.mod go build with CGO_ENABLED=0 Static ELF binary
node package.json npm install --production Uses node runtime package
python pyproject.toml / requirements.txt pip install -r requirements.txt Uses python runtime package
rust Cargo.toml cargo build --release --target <triple> Static ELF binary via musl

unikernel.toml Configuration:

When uni build is run on a directory, it automatically reads unikernel.toml if present:

[build]
lang = "go"
entrypoint = "cmd/server"
args = ["-v"]

[run]
memory = "512M"
cpus = 2
ports = ["8080:80", "9090:9090"]

[env]
NODE_ENV = "production"

Multi-stage Builds:

unikernel.toml also supports multi-stage builds with [[stages]]. Each stage is built independently, and copy_from directives copy artifacts from previous stages:

[[stages]]
name = "builder"
lang = "go"
entrypoint = "cmd/server"

[[stages]]
name = "runtime"
lang = "node"
entrypoint = "server.js"

[[stages.copy_from]]
stage = "builder"
src = "/app/server"
dst = "server"

The final stage’s output is used as the image binary. Earlier stages produce intermediate build artifacts that can be copied into later stages.

.unignore File:

Exclude files from the build context with .unignore (similar to .dockerignore):

# Comment
*.log
build/
.git
node_modules
!important.log

Output:

sha256:abc123def456...  api:latest

uni images

List all images in the local store.

uni images

Example:

uni images
# DIGEST              NAME   TAG     CREATED               SIZE
# sha256:abc123def4   hello  latest  2026-04-19T10:00:00Z  12.0MB
# sha256:def456ghi7   api    v1.2.0  2026-04-19T11:00:00Z  24.3MB

uni rmi

Remove an image from the local store.

uni rmi <ref>

<ref> can be name:tag or sha256:<hex>.

Example:

uni rmi hello:latest
# hello:latest

uni push

Push a local image to a registry.

uni push now prefers the OCI Distribution flow (/v2/<name>/blobs/... + /v2/<name>/manifests/<tag>). If the target registry does not support OCI endpoints yet, it automatically falls back to the legacy /v2/images API.

Registry auth/TLS options are available as global flags:

  • --registry-token (or UNI_REGISTRY_TOKEN) to send bearer/JWT auth
  • --registry-ca-cert (or UNI_REGISTRY_CA_CERT) to trust a custom CA
  • --registry-insecure (or UNI_REGISTRY_INSECURE=true) to skip TLS verification in development
uni push <ref> <registry-url>

Example:

uni push hello:latest http://registry.example.com:5000
# pushed hello:latest to http://registry.example.com:5000

uni pull

Pull an image from a registry into the local store.

uni pull now prefers the OCI Distribution flow and automatically falls back to the legacy /v2/images API when needed.

The same global registry auth/TLS flags used by uni push apply to uni pull.

uni pull <ref> <registry-url>

Example:

uni pull hello:latest http://registry.example.com:5000
# sha256:abc123...  hello:latest

# Pull with signature verification
uni pull hello:latest http://registry.example.com:5000 --verify enforce

Flags:

Flag Default Description
--verify off Image signature verification: off, warn, enforce

Search remote registry repositories using OCI catalog data.

uni search <registry>/<query>

Example:

uni search https://registry.example.com:5000/hello
# hello
# hello-api

uni search supports the same global registry auth/TLS flags as uni push/uni pull.


uni sign

Sign a local image with the default Ed25519 key pair. If no key pair exists, one is generated automatically and stored in ~/.uni/keys/.

uni sign <image>

Example:

uni sign hello:latest
# signed hello:latest (key a1b2c3d4e5f67890, digest sha256:...)

uni verify

Verify the Ed25519 signature of a local image. Fails if the image has no signature or the signature is invalid.

uni verify <image>

Example:

uni verify hello:latest
# verified hello:latest (key a1b2c3d4e5f67890, digest sha256:...)

Package Commands

Manage pre-packaged files that can be included in images at build time. Packages are cached locally in ~/.uni/packages/.

uni pkg list

List locally cached packages.

uni pkg list
uni pkg list
# NAME       VERSION   SIZE
# redis      7.2       12.5MB
# nginx      1.25      8.3MB

Search the remote package index.

uni pkg search <query>
uni pkg search redis
# NAME       VERSION   SIZE      DESCRIPTION
# redis      7.2       12.5MB    In-memory data store
# redis-cli  7.2       3.1MB     Redis command-line client

uni pkg get

Download and install a package from the remote index.

uni pkg get <name>[:version]
# Install the latest version
uni pkg get redis

# Install a specific version
uni pkg get redis:7.2

uni pkg remove

Remove locally cached package(s). Without a version suffix, all versions of the package are removed.

uni pkg remove <name>[:version]
# Remove a specific version
uni pkg remove redis:7.2

# Remove all locally cached versions
uni pkg remove redis
# Removed all versions of package redis.

uni pkg create

Create a local package from a binary and optional additional files. The package archive is stored in the local package cache.

uni pkg create <name>[:<version>] <binary> [--libs <file>...] [--description <desc>] [--runtime <runtime>] [--missing-files]

If no version is specified, 1.0.0 is used as the default.

The --missing-files flag analyses the binary with ldd and reports shared library dependencies that are missing from the local filesystem. This is useful for identifying which libraries need to be included with --libs.

# Create a package from a static binary
uni pkg create myapp:1.2.0 ./myapp --description "My application" --runtime custom

# Create a package with additional library files
uni pkg create myapp:1.2.0 ./myapp --libs ./libmyapp.so --description "With shared lib"

# Check for missing shared library dependencies
uni pkg create myapp:1.2.0 ./myapp --missing-files
# Missing shared libraries detected (not on local filesystem):
#   /lib/x86_64-linux-gnu/libssl.so.3
#   /lib/x86_64-linux-gnu/libcrypto.so.3
# Consider adding these with --libs or re-running with the binary on a Linux system.

# Create with auto-resolved shared libs from ldd
uni pkg create myapp:1.2.0 ./myapp

# Create with auto-default version (1.0.0)
uni pkg create myapp ./myapp

uni pkg from-docker

Extract a binary and its shared library dependencies from a Docker image, creating a local package. Uses docker create + docker cp to extract the binary, then runs ldd inside the container to discover shared libraries.

uni pkg from-docker <name>[:<version>] <image> --file <path> [--libs <path>...] [--description <desc>] [--runtime <runtime>]
Flag Default Description
--file (required) Path to the binary inside the Docker image
--libs Additional library paths inside the container to include (repeatable)
--description "" Package description
--runtime "" Runtime family (e.g. node, python)
# Extract Node.js from the official Docker image
uni pkg from-docker node:20 node:20 --file /usr/local/bin/node --runtime node

# Extract Redis with extra libraries
uni pkg from-docker redis:7 redis:7 --file /usr/local/bin/redis-server --libs /usr/local/bin/redis-cli --runtime redis

# Extract with auto-detected shared libraries
uni pkg from-docker myapp:1.0 myapp:latest --file /app/myapp --description "My app from Docker"

uni pkg push

Push a locally cached package to a remote package index. The index server must support POST /packages with multipart form data (archive + metadata).

uni pkg push <name>:<version> <index-url>

The version is required. Use uni pkg list to see locally cached packages.

# Push a package to a remote index
uni pkg push node:20 https://packages.example.com

# Push a locally created package
uni pkg push myapp:1.2.0 https://packages.example.com

Volume Commands

Volumes are named persistent disk images that survive VM restarts. Create a volume once, then mount it into any VM with -v.

uni volume create

Create a new named volume.

uni volume create <name> [--size <size>]
Flag Default Description
--size 1G Volume size: 512M, 1G, 2G, etc.

Example:

uni volume create mydata --size 2G
# mydata

uni volume create config --size 512M
# config

uni volume ls

List all volumes.

uni volume ls [--output json]
uni volume ls
# NAME     SIZE   CREATED
# mydata   2.0G   2026-04-25 18:00:00
# config   512.0M 2026-04-25 18:01:00

uni volume inspect

Show full details for a volume as JSON.

uni volume inspect <name>
uni volume inspect mydata
{
  "id": "mydata",
  "disk_path": "/home/user/.uni/volumes/mydata/disk.img",
  "size_bytes": 2147483648,
  "created_at": "2026-04-25T18:00:00Z"
}

uni volume rm

Remove a volume and its disk image permanently.

uni volume rm <name>

This is irreversible. All data stored in the volume will be lost.

uni volume rm mydata
# mydata

Network and DNS Commands

uni network create

Create a managed network. When --subnet is omitted, Uni auto-allocates a /24 from 10.100.0.0/16.

uni network create <name> [--subnet <cidr>] [--driver bridge]

uni dns resolve

Resolve a running VM/service name to its IP address.

uni dns resolve <name> [--network <name>]

Examples:

uni dns resolve frontend --network app
uni dns resolve frontend.app

If the same service name exists in multiple networks, --network (or name.network) is required.

uni dns list

List resolvable records from running VMs.

uni dns list [--network <name>]

Cluster Commands

uni node ls

List cluster members with status and resource capacity.

uni node ls

Example:

uni node ls
# ID              ADDR             STATUS   VMS   CPU   MEM       SEEN
# a1b2c3d4        10.0.0.1:7946    alive    3     8     16.0 GiB  2026-05-16T10:00:00Z
# e5f6a7b8        10.0.0.2:7946    suspect  1     4     8.0 GiB   2026-05-16T09:55:00Z

# JSON output
uni --output json node ls

Requires --cluster-addr on the unid daemon. When cluster is disabled, uni node ls returns an error.


Kernel Commands

Manage the kernel tools (kernel.img, boot.img, mkfs) cached in ~/.uni/tools/. The kernel is versioned independently from the CLI.

uni kernel check

Show the installed kernel version and whether a newer one is available.

uni kernel check
uni kernel check
# Installed kernel: v0.1.0
# Latest kernel:    v0.1.1
# Update available. Run `uni kernel update` to install v0.1.1.

uni kernel update

Download and install the latest kernel tools.

uni kernel update [--yes]
Flag Default Description
-y, --yes false Skip confirmation prompt
uni kernel update
# New kernel version available: v0.1.1 (installed: v0.1.0)
# Update? [y/N] y
# Downloading kernel.img...
# Kernel updated to v0.1.1.

uni kernel list

List all available kernel versions, newest first. The currently installed version is marked with *.

uni kernel list
uni kernel list
# * v0.1.1
#   v0.1.0

uni kernel use

Switch to a specific kernel version.

uni kernel use <version> [--yes]
Flag Default Description
-y, --yes false Skip confirmation prompt
uni kernel use v0.1.0
# Switching kernel: v0.1.1 → v0.1.0
# Proceed? [y/N] y
# Kernel switched to v0.1.0.

Upgrade Commands

Manage the uni and unid binaries themselves. The CLI is versioned independently from the kernel.

uni upgrade

Download and install the latest uni (and unid if found alongside it), replacing the running binaries in-place.

uni upgrade [--yes]
Flag Default Description
-y, --yes false Skip confirmation prompt
uni upgrade
# Installed: v0.1.0
# Latest:    v0.1.1
# New version available: v0.1.1
# Upgrade? [y/N] y
# Downloading uni-linux-amd64...
# Downloading unid-linux-amd64...
# Upgraded to v0.1.1.

On Windows, the running binary is renamed to .bak before the new one is placed in its position, since Windows does not allow overwriting a running executable directly. After the upgrade completes successfully, old .bak files are cleaned up automatically.


uni upgrade check

Show the installed CLI version and whether a newer one is available, without installing anything.

uni upgrade check
uni upgrade check
# Installed: v0.1.0
# Latest:    v0.1.1
# Update available. Run `uni upgrade` to install v0.1.1.

uni upgrade list

List all available CLI versions, newest first. The currently running version is marked with *.

uni upgrade list
uni upgrade list
#   v0.1.1
# * v0.1.0

Compose Commands

See the full Compose Reference for the file format.

uni compose up

Start all services defined in a compose file, in dependency order.

uni compose up <compose-file>

Example:

uni compose up stack.yaml
# started backend → a3f8c2d1-...
# started frontend → b4e9d3e2-...

uni compose down

Stop all services from a compose file, in reverse dependency order.

uni compose down <compose-file> [--force] [--volumes]
Flag Default Description
--force false SIGKILL immediately
--volumes false Remove volumes defined in the compose volumes: section

uni compose ps

List the state of all services in a compose stack.

uni compose ps <compose-file>
uni compose ps stack.yaml
# SERVICE   ID                                    STATE
# backend   a3f8c2d1-7b4e-4a1f-8c2d-...          running
# frontend  b4e9d3e2-8c5f-5b2g-9d3e-...          running

uni --output json compose ps stack.yaml

uni compose logs

Print serial console output for a specific service.

uni compose logs <compose-file> <service>
uni compose logs stack.yaml backend

VM States

created → starting → running → stopping → stopped
State Description
created VM registered, QEMU not started yet
starting QEMU process being launched
running QEMU process alive and booting/running
stopping Stop signal sent, waiting for process exit
stopped QEMU process has exited

A VM in stopped state can be removed with uni rm. It cannot be restarted — create a new VM with uni run.

When using uni run --attach, the command blocks until the VM reaches the stopped state, streaming all serial console output to stdout during the running state.


Daemon Flags

unid is the background daemon that manages VMs. It accepts the following flags:

Flag Default Description
--socket /var/run/unid.sock (Linux) / %TEMP%\unid.sock (Windows) Unix socket path for VM management API
--qemu qemu-system-x86_64 QEMU binary to use
--registry-addr (empty, disabled) HTTP address for image registry (e.g. :5000)
--registry-token $UNI_REGISTRY_TOKEN Bearer token for registry auth
--registry-jwt-secret $UNI_REGISTRY_JWT_SECRET JWT HMAC secret for scoped registry auth
--registry-jwt-issuer $UNI_REGISTRY_JWT_ISSUER Expected JWT issuer for registry auth
--registry-jwt-audience $UNI_REGISTRY_JWT_AUDIENCE Expected JWT audience for registry auth
--registry-tls-cert $UNI_REGISTRY_TLS_CERT TLS cert file for registry HTTPS
--registry-tls-key $UNI_REGISTRY_TLS_KEY TLS key file for registry HTTPS
--store ~/.uni/images Image store root directory
--metrics-addr (empty, disabled) HTTP address for Prometheus metrics (e.g. :9090)
--ui-addr (empty, disabled) HTTP address for web dashboard (e.g. :8080)
--log-format text Log format: text (default) or json
--trace-addr (empty, disabled) OTLP gRPC address for trace export (e.g. localhost:4317)
--cluster-addr (empty, disabled) HTTP address for cluster gossip endpoint (e.g. :7946)
--join (empty) Comma-separated list of seed node addresses to join (e.g. 10.0.0.2:7946)

Observability Endpoints

When --metrics-addr is set, unid exposes:

Path Description
/metrics Prometheus metrics endpoint
/health Health check endpoint (returns 200 ok)

When --log-format json is set, all daemon logs are structured JSON lines with ts, level, msg, and custom attributes.

When --trace-addr is set, unid exports OpenTelemetry traces via OTLP gRPC for VM lifecycle events (create, start, stop, kill, remove).

Dashboard

When --ui-addr is set, unid serves a web dashboard:

Path Description
/ui VM list with state and health
/ui/api/vms JSON endpoint for VM list

The dashboard shows all registered VMs with their ID, name, state, health status, and image. It auto-refreshes via the /ui/api/vms endpoint.

VM Runtime Stats

uni stats <id> queries the daemon for runtime resource usage of a VM. Stats are collected from the QEMU process:

  • CPU% — percentage of CPU(s) used by the VM process (Linux only, via /proc/[pid]/stat)
  • Memory — resident set size in bytes (Linux only, via /proc/[pid]/statm)
  • Network I/O — bytes received/transmitted on the primary interface (eth0 or en*) (Linux only, via /proc/[pid]/net/dev)
  • Sourceprocfs on Linux, fallback on other platforms

Use --watch for continuous monitoring:

uni stats <id> --watch
uni stats <id> --watch --interval 5s

Released under the MIT License.