A multi-hypervisor VM runtime for OCI images, supporting Cloud Hypervisor, Firecracker, QEMU, and Apple Virtualization.framework.
346
stars
313
commits
Go
primary language
Sep 10, 2026
updated
██╗ ██╗ ██╗ ██╗ ██████╗ ███████╗ ███╗ ███╗ █████╗ ███╗ ██╗
██║ ██║ ╚██╗ ██╔╝ ██╔══██╗ ██╔════╝ ████╗ ████║ ██╔══██╗ ████╗ ██║
███████║ ╚████╔╝ ██████╔╝ █████╗ ██╔████╔██║ ███████║ ██╔██╗ ██║
██╔══██║ ╚██╔╝ ██╔═══╝ ██╔══╝ ██║╚██╔╝██║ ██╔══██║ ██║╚██╗██║
██║ ██║ ██║ ██║ ███████╗ ██║ ╚═╝ ██║ ██║ ██║ ██║ ╚████║
╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝
Run containerized workloads in VMs, powered by Cloud Hypervisor, Firecracker, QEMU, and Apple Virtualization.framework.
run, exec, stop, ps, logs, pull work like you'd expectKVM virtualization support required. Supports Cloud Hypervisor, Firecracker, and QEMU as hypervisors.
macOS 11.0+ on Apple Silicon. Uses Apple's Virtualization.framework via the vz hypervisor.
Install Rosetta to run linux/amd64 images on Apple Silicon:
softwareupdate --install-rosetta --agree-to-license
Install Hypeman (Linux and macOS supported):
curl -fsSL https://get.hypeman.sh | bash
This installs the Hypeman server, CLI, and token tool. The installer:
~/.config/hypeman/cli.yaml) with a pre-authenticated tokenNo environment variables needed -- just run hypeman commands immediately after install.
To use the Hypeman CLI from a different machine than the server:
Homebrew (macOS):
brew install kernel/tap/hypeman
Install script (Linux & macOS):
curl -fsSL https://get.hypeman.sh/cli | bash
Go:
go install 'github.com/kernel/hypeman-cli/cmd/hypeman@latest'
Then create a CLI config file at ~/.config/hypeman/cli.yaml:
base_url: http://<server-host>:4973
api_key: "<token>"
To generate a token, run hypeman-token on the server:
hypeman-token -user-id "my-user" -duration 8760h
Environment variables (HYPEMAN_BASE_URL, HYPEMAN_API_KEY) and CLI flags (--base-url) also work and take precedence over the config file.
Hypeman is configured via YAML config files.
| Component | Config File |
|---|---|
| Server | /etc/hypeman/config.yaml (Linux) or ~/.config/hypeman/config.yaml (macOS) |
| CLI | ~/.config/hypeman/cli.yaml |
See config.example.yaml (Linux) and config.example.darwin.yaml (macOS) for all available server options.
To expose the API through Caddy on a public HTTPS hostname, configure the hostname and TLS in the server config. The hostname must also be included in acme.allowed_domains:
api:
hostname: api.example.com
tls: true
redirect_http: true
With this configuration, use https://api.example.com as the API base URL. Without it, the API is available on the server's configured port (4973 by default).
# Pull an image
hypeman pull nginx:alpine
# Boot a new VM (auto-pulls image if needed)
hypeman run --name my-app nginx:alpine
# On Linux amd64, use QEMU's minimal microvm backend.
# It cannot use PCI devices or hotplug memory.
hypeman run --hypervisor qemu-microvm --name my-microvm nginx:alpine
# List running VMs
hypeman ps
# Show all VMs
hypeman ps -a
# View logs (supports VM name, ID, or partial ID)
hypeman logs my-app
hypeman logs -f my-app
# Execute a command in a running VM
hypeman exec my-app whoami
# Shell into the VM
hypeman exec -it my-app /bin/sh
A ready image can be exported asynchronously to any OCI registry through the remote API. Set the API base URL and API key used by the examples below:
export HYPEMAN_BASE_URL="https://api.example.com"
export HYPEMAN_API_KEY="<api-key>"
Credentials use the Docker model:
credentials is provided, the client lends username/password or
registry_token for this push only. Hypeman uses them in memory and never
persists or logs them.credentials is omitted, Hypeman uses the server's Docker keychain,
including /root/.docker/config.json or the configured service user's
~/.docker/config.json and any credential helpers.Use an HTTPS API URL when sending credentials. The insecure request field
controls only the connection from Hypeman to the destination registry.
For example, push to ECR using a short-lived login password:
export ECR_PASSWORD="$(aws ecr get-login-password --region us-east-1)"
curl --fail-with-body --silent --show-error \
-X POST "$HYPEMAN_BASE_URL/pushes" \
-H "Authorization: Bearer $HYPEMAN_API_KEY" \
-H "Content-Type: application/json" \
--data "{
\"image\": \"myapp:latest\",
\"target\": \"123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:v1\",
\"credentials\": {
\"username\": \"AWS\",
\"password\": \"$ECR_PASSWORD\"
}
}"
The response contains a push id. Poll it until the status is pushed or
failed:
curl --fail-with-body --silent --show-error \
"$HYPEMAN_BASE_URL/pushes/<push-id>" \
-H "Authorization: Bearer $HYPEMAN_API_KEY"
Push jobs move through queued, pushing, and pushed or failed.
queue_position is present while a job is queued; successful jobs report
layers, bytes, and completed_at, while failed jobs report error.
GET /pushes lists jobs newest first.
Set "insecure": true only when the destination registry uses plain HTTP.
HTTPS registries do not need this option. Invalid image names or targets return
400, a missing image returns 404, and only images in the ready state can
be pushed (409 image_not_ready otherwise).
Layer blobs are preserved. OCI manifest digests are preserved too, while a
Docker v2 manifest is converted to OCI and can therefore receive a new digest;
use the returned digest as the destination manifest digest.
The default limit is two concurrent pushes. Increase or lower it with:
limits:
max_concurrent_pushes: 2
# Stop the VM
hypeman stop my-app
# Start a stopped VM
hypeman start my-app
# Put the VM in standby (snapshot to disk, stop hypervisor)
hypeman standby my-app
# Restore the VM from standby
hypeman restore my-app
# Delete all VMs
hypeman rm --force --all
Create a reverse proxy from the host to your VM:
# Create an ingress
hypeman ingress create --name my-ingress my-app --hostname my-nginx-app --port 80 --host-port 8081
# List ingresses
hypeman ingress list
# Test it
curl --header "Host: my-nginx-app" http://127.0.0.1:8081
# Delete an ingress
hypeman ingress delete my-ingress
# TLS-terminating ingress (requires DNS credentials in server config)
hypeman ingress create --name my-tls-ingress my-app \
--hostname hello.example.com -p 80 --host-port 7443 --tls
# Test TLS
curl --resolve hello.example.com:7443:127.0.0.1 https://hello.example.com:7443
# Subdomain-based routing
hypeman ingress create --name subdomain-ingress '{instance}' \
--hostname '{instance}.example.com' -p 80 --host-port 8443 --tls
# Delete all ingresses
hypeman ingress delete --all
# View Cloud Hypervisor logs
hypeman logs --source vmm my-app
# View Hypeman operational logs
hypeman logs --source hypeman my-app
For all available commands, run hypeman --help.
See DEVELOPMENT.md for build instructions, configuration options, and contributing guidelines.
See LICENSE.
Go
97.4%
Shell
2.1%
A multi-hypervisor VM runtime for OCI images, supporting Cloud Hypervisor, Firecracker, QEMU, and Apple Virtualization.framework.
346
stars
313
commits
Go
primary language
Sep 10, 2026
updated
██╗ ██╗ ██╗ ██╗ ██████╗ ███████╗ ███╗ ███╗ █████╗ ███╗ ██╗
██║ ██║ ╚██╗ ██╔╝ ██╔══██╗ ██╔════╝ ████╗ ████║ ██╔══██╗ ████╗ ██║
███████║ ╚████╔╝ ██████╔╝ █████╗ ██╔████╔██║ ███████║ ██╔██╗ ██║
██╔══██║ ╚██╔╝ ██╔═══╝ ██╔══╝ ██║╚██╔╝██║ ██╔══██║ ██║╚██╗██║
██║ ██║ ██║ ██║ ███████╗ ██║ ╚═╝ ██║ ██║ ██║ ██║ ╚████║
╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝
Run containerized workloads in VMs, powered by Cloud Hypervisor, Firecracker, QEMU, and Apple Virtualization.framework.
run, exec, stop, ps, logs, pull work like you'd expectKVM virtualization support required. Supports Cloud Hypervisor, Firecracker, and QEMU as hypervisors.
macOS 11.0+ on Apple Silicon. Uses Apple's Virtualization.framework via the vz hypervisor.
Install Rosetta to run linux/amd64 images on Apple Silicon:
softwareupdate --install-rosetta --agree-to-license
Install Hypeman (Linux and macOS supported):
curl -fsSL https://get.hypeman.sh | bash
This installs the Hypeman server, CLI, and token tool. The installer:
~/.config/hypeman/cli.yaml) with a pre-authenticated tokenNo environment variables needed -- just run hypeman commands immediately after install.
To use the Hypeman CLI from a different machine than the server:
Homebrew (macOS):
brew install kernel/tap/hypeman
Install script (Linux & macOS):
curl -fsSL https://get.hypeman.sh/cli | bash
Go:
go install 'github.com/kernel/hypeman-cli/cmd/hypeman@latest'
Then create a CLI config file at ~/.config/hypeman/cli.yaml:
base_url: http://<server-host>:4973
api_key: "<token>"
To generate a token, run hypeman-token on the server:
hypeman-token -user-id "my-user" -duration 8760h
Environment variables (HYPEMAN_BASE_URL, HYPEMAN_API_KEY) and CLI flags (--base-url) also work and take precedence over the config file.
Hypeman is configured via YAML config files.
| Component | Config File |
|---|---|
| Server | /etc/hypeman/config.yaml (Linux) or ~/.config/hypeman/config.yaml (macOS) |
| CLI | ~/.config/hypeman/cli.yaml |
See config.example.yaml (Linux) and config.example.darwin.yaml (macOS) for all available server options.
To expose the API through Caddy on a public HTTPS hostname, configure the hostname and TLS in the server config. The hostname must also be included in acme.allowed_domains:
api:
hostname: api.example.com
tls: true
redirect_http: true
With this configuration, use https://api.example.com as the API base URL. Without it, the API is available on the server's configured port (4973 by default).
# Pull an image
hypeman pull nginx:alpine
# Boot a new VM (auto-pulls image if needed)
hypeman run --name my-app nginx:alpine
# On Linux amd64, use QEMU's minimal microvm backend.
# It cannot use PCI devices or hotplug memory.
hypeman run --hypervisor qemu-microvm --name my-microvm nginx:alpine
# List running VMs
hypeman ps
# Show all VMs
hypeman ps -a
# View logs (supports VM name, ID, or partial ID)
hypeman logs my-app
hypeman logs -f my-app
# Execute a command in a running VM
hypeman exec my-app whoami
# Shell into the VM
hypeman exec -it my-app /bin/sh
A ready image can be exported asynchronously to any OCI registry through the remote API. Set the API base URL and API key used by the examples below:
export HYPEMAN_BASE_URL="https://api.example.com"
export HYPEMAN_API_KEY="<api-key>"
Credentials use the Docker model:
credentials is provided, the client lends username/password or
registry_token for this push only. Hypeman uses them in memory and never
persists or logs them.credentials is omitted, Hypeman uses the server's Docker keychain,
including /root/.docker/config.json or the configured service user's
~/.docker/config.json and any credential helpers.Use an HTTPS API URL when sending credentials. The insecure request field
controls only the connection from Hypeman to the destination registry.
For example, push to ECR using a short-lived login password:
export ECR_PASSWORD="$(aws ecr get-login-password --region us-east-1)"
curl --fail-with-body --silent --show-error \
-X POST "$HYPEMAN_BASE_URL/pushes" \
-H "Authorization: Bearer $HYPEMAN_API_KEY" \
-H "Content-Type: application/json" \
--data "{
\"image\": \"myapp:latest\",
\"target\": \"123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:v1\",
\"credentials\": {
\"username\": \"AWS\",
\"password\": \"$ECR_PASSWORD\"
}
}"
The response contains a push id. Poll it until the status is pushed or
failed:
curl --fail-with-body --silent --show-error \
"$HYPEMAN_BASE_URL/pushes/<push-id>" \
-H "Authorization: Bearer $HYPEMAN_API_KEY"
Push jobs move through queued, pushing, and pushed or failed.
queue_position is present while a job is queued; successful jobs report
layers, bytes, and completed_at, while failed jobs report error.
GET /pushes lists jobs newest first.
Set "insecure": true only when the destination registry uses plain HTTP.
HTTPS registries do not need this option. Invalid image names or targets return
400, a missing image returns 404, and only images in the ready state can
be pushed (409 image_not_ready otherwise).
Layer blobs are preserved. OCI manifest digests are preserved too, while a
Docker v2 manifest is converted to OCI and can therefore receive a new digest;
use the returned digest as the destination manifest digest.
The default limit is two concurrent pushes. Increase or lower it with:
limits:
max_concurrent_pushes: 2
# Stop the VM
hypeman stop my-app
# Start a stopped VM
hypeman start my-app
# Put the VM in standby (snapshot to disk, stop hypervisor)
hypeman standby my-app
# Restore the VM from standby
hypeman restore my-app
# Delete all VMs
hypeman rm --force --all
Create a reverse proxy from the host to your VM:
# Create an ingress
hypeman ingress create --name my-ingress my-app --hostname my-nginx-app --port 80 --host-port 8081
# List ingresses
hypeman ingress list
# Test it
curl --header "Host: my-nginx-app" http://127.0.0.1:8081
# Delete an ingress
hypeman ingress delete my-ingress
# TLS-terminating ingress (requires DNS credentials in server config)
hypeman ingress create --name my-tls-ingress my-app \
--hostname hello.example.com -p 80 --host-port 7443 --tls
# Test TLS
curl --resolve hello.example.com:7443:127.0.0.1 https://hello.example.com:7443
# Subdomain-based routing
hypeman ingress create --name subdomain-ingress '{instance}' \
--hostname '{instance}.example.com' -p 80 --host-port 8443 --tls
# Delete all ingresses
hypeman ingress delete --all
# View Cloud Hypervisor logs
hypeman logs --source vmm my-app
# View Hypeman operational logs
hypeman logs --source hypeman my-app
For all available commands, run hypeman --help.
See DEVELOPMENT.md for build instructions, configuration options, and contributing guidelines.
See LICENSE.
Go
97.4%
Shell
2.1%