One control planefor any compute.
Deploy apps, databases. Run jobs and sandboxes. Whatever runs in a container, with HTTPS, logs and private networking built in, on any machine you connect or on Unisrv capacity.
Bare metal, a VPS, a cloud VM and a homelab server you own, plus Unisrv capacity, all connect to one Unisrv control plane, which places your applications across them: web on the homelab server, postgres with its volume on the bare-metal server, and a one-off migration that ran and exited on Unisrv capacity.
Connect a machine. Deploy.It's live, from any hardware.
Run the command the console gives you on any Linux machine. The node dials out, so NAT & firewalls are fine. Then treat Unisrv as any streamlined PaaS, but using your hardware for compute.
The runtime and local orchestrator are conveniently packaged as a container image, so all you need is Docker or Podman to run it privileged for spawning containers or microVMs.
- ConnectConnect a machine
- DeployDeploy
- LiveLive
The CLI never names a node. Your server's log shows the app arriving.
Anything in a container. On any machine.
Declared in unisrv.hcl and applied with unisrv up, or run once from the CLI.
Web app
A domain, its certificate, and the deployment it routes to.
unisrv.hclproject = "unisrv-io" service "unisrv" { hosts = ["unisrv.io"] location "/" { deployment = "web-ssr" } } deployment "web-ssr" { port = 80 container { image = "ghcr.io/unisrv/unisrv-io:latest" } }The whole file that deploys unisrv.io. Of course we self-host :)
App + database
Postgres keeps its volume through restarts and rollouts. The api reaches it by name.
unisrv.hcldeployment "api" { port = 8000 network = "internal" container { image = "ghcr.io/acme/api:1.4" env = { PGHOST = "postgres" } } } deployment "postgres" { network = "internal" container { image = "postgres:17" env = { POSTGRES_PASSWORD = var.db_password } } volume { mount_path = "/var/lib/postgresql/data" size = "10GB" } } network "internal" {}One-off task
Runs to completion and exits with the container's code. On a node with KVM, each one is its own Firecracker microVM.
terminalunisrv instance run --rm python:3.13 python3 -c "$AGENT_CODE" unisrv instance run --rm alpine echo hello [09:14:12] Image ready: library/alpine:latest -> sha256:d56c381f961d… 57.5 MB in 563ms [09:14:13] state: online [09:14:13] Instance v. 0.1.0 [09:14:13] state: pulling_container_image [09:14:13] state: executing_container hello [09:14:13] Container exited with code: 0 after 8msPreview per PR
The same file under another environment name is an independent copy, at its own *.unisrv.dev address.
terminal# in CI, for every pull request unisrv up -y --env pr-42 --var tag=$GIT_SHA # once it merges unisrv destroy -y --env pr-42
None of these name a machine: the control plane picks one.
Your servers, ours, or both.
A node is any Linux machine running the Unisrv runtime, yours or ours. Nothing in unisrv.hcl changes when the machine does.
Bring your compute
Connect any Linux machine you have, even one behind NAT.
Use Unisrv compute
Deploy without a server of your own. Allocated per invite during the alpha.
Mix them
Run both in one environment, under one control plane.
- fsn1-metal-01Hetzner · bare metalOwner: YoursIsolation: microVMCapacity: 32 vCPU · 128 GBStatus: Active
- homelab-nucHome · behind NATOwner: YoursIsolation: microVMCapacity: 8 vCPU · 32 GBStatus: Active
- ec2-eun1-01AWS · EC2 m7i.xlargeOwner: YoursIsolation: containerCapacity: 4 vCPU · 16 GBStatus: Active
- gra-vps-02OVH · VPSOwner: YoursIsolation: containerCapacity: 4 vCPU · 8 GBStatus: Active
- Unisrv capacitysto1-aOwner: UnisrvIsolation: microVMCapacity: managed by UnisrvStatus: Managed
One environment's nodes and what runs on each.
Our architectureA runtime and control plane with an opinionated interface.
The Unisrv runtime spawns and orchestrates containers as instances on every node, so a rented server, your own rack and Unisrv capacity behave as one platform. The control plane decides what runs where. Networking dials out, so no port forwarding is needed.
A four layer stack. Unisrv provides the top three: the interface you declare a project in, the control plane that holds desired state and places instances, and the runtime that runs them on every node. The fourth layer, the hardware underneath, is yours: bare metal, a VPS, a cloud VM, a homelab, or capacity Unisrv provides.
- Desired state
unisrv upsends what you declared and the control plane acts on the difference. Kubernetes' reconciliation model, without a cluster to run.- Placement
- The control plane picks a node per instance. Instances don't move, and a volume pins its replica to its node.
- Isolation
- Firecracker microVMs for untrusted code, plain containers on hosts that are already VMs. Same deployment either way.
- Service discovery
- Deployments on one internal network reach each other by name, across nodes.
No inbound ports, port forwarding or public IP.
Your node, inside your own network behind NAT, dials out to the Unisrv edge over QUIC, and requests come back down that connection, secured with mutual TLS 1.3. Your IP stays private and your nodes stay off the public internet.
Node-to-node traffic rides the same encrypted transport, and public TLS terminates at the edge.
What you get.
Compute
- InstancesEphemeral runs of containers as instances. Spawned by deployments, or one-shots for jobs, agentic sandboxes or just a random VM. Automatic placement over any compute.
- DeploymentsReplicas of an instance with lifecycle handling towards a desired state. Stateless workloads like APIs or stateful ones like databases when using volumes.
replicas = 0can scale it to zero. - Ephemeral environmentsBuilt-in support for throwaway environments, for a per-PR environment workflow.
Networking
Your compute.One control plane.
Unisrv is in closed private alpha. We are looking for alpha users.