cd /news/developer-tools/show-hn-bastion-self-hosted-vms-for-… · home topics developer-tools article
[ARTICLE · art-49451] src=github.com ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Show HN: Bastion – self-hosted VMs for background coding agents

Bastion, an open-source orchestrator for running background coding agents on self-hosted Linux infrastructure, was released. Each agent runs in a separate Cloud Hypervisor VM with a reproducible dev environment, supporting declarative setup, prepared snapshots, and multi-node clustering. The tool aims to simplify scaling coding agents with VM-level isolation and direct access via SSH or a TUI.

read4 min views1 publishedJul 7, 2026
Show HN: Bastion – self-hosted VMs for background coding agents
Image: source

Self-hosted virtual computers for background coding agents.

Website · Docs · Quick start · Demo · Discussions

Bastion is an open-source orchestrator for running background coding agents on your own Linux infrastructure. Each agent runs in a separate Cloud Hypervisor VM with a reproducible dev environment.

Define an environment in JSON, prepare it once as a snapshot, and create disposable VMs for parallel tasks. Bastion can run on a single KVM host or schedule environments across an optional multi-node cluster.

Bastion makes it easy to scale background coding agents into reproducible environments.

VM-level isolation: each environment has its own guest kernel, root filesystem, processes, and network.Declarative setup: define CPU, memory, disk, agents, service tunnels, and lifecycle actions in schema-validated JSON.Prepared snapshots: install dependencies during template creation, then replicate isolated copy-on-write environments from that prepared state.Direct access: connect through SSH, attach a local OpenCode TUI, or usebastion mux

to move between persistent sessions.Conflict-free previews: expose dev servers on the guest VM through named tunnels for host side previews.Self-hosted control: start on one Linux machine, then add the cluster control plane when a single host is not enough.

The host needs:

  • Linux on x86_64
  • read/write access to /dev/kvm

/dev/vhost-vsock

for VM tunnel traffic- nested virtualization when the host is itself a VM

curl -fsSL https://bastion.computer/install.sh | bash

bastion system check
bastion system init --with-utilities

The installer adds the bastion

CLI, guest proxy, and systemd services for the host API and privileged VM daemon. Release archives are also available from GitHub Releases.

cat > template.json <<'JSON'
{
  "resources": {
    "vcpu": 2,
    "memory": 2,
    "volume": 20
  },
  "agents": {
    "opencode": {}
  },
  "actions": {
    "init": [
      {
        "run": "mkdir -p /workspace && printf 'hello from Bastion\\n' > /workspace/README.md"
      }
    ]
  }
}
JSON

bastion templates create --key hello --file ./template.json

Template creation boots a temporary VM, runs actions.init

, and stores an immutable prepared root disk and VM snapshot.

bastion env create --template-key hello --key agent-1
bastion ssh --key agent-1 -- cat /workspace/README.md
bastion ssh --key agent-1

With OpenCode installed locally, attach its TUI to the server inside the environment:

bastion opencode --key agent-1

Or open Bastion's tmux-based environment picker:

bastion mux

Clean up when finished:

bastion env remove --key agent-1
bastion templates remove --key hello

For a complete parallel-agent walkthrough, see the Bastion issue tracker demo. It includes a Bun/TypeScript app, a reusable environment template, service previews, and five independent coding tasks.

flowchart LR
    Client["CLI / API client"] --> API["Host API<br/>unprivileged · SQLite"]
    API -->|Unix socket| Daemon["bastiond<br/>privileged VM operations"]
    Daemon --> VM1["Cloud Hypervisor VM<br/>agent-1"]
    Daemon --> VM2["Cloud Hypervisor VM<br/>agent-2"]
    Daemon --> VMN["Cloud Hypervisor VM<br/>agent-n"]

The local control plane is split into two processes:

bastion start api

stores metadata, serves the HTTP API onlocalhost:3148

by default, and runs without root privileges.bastion start daemon

performs privileged Cloud Hypervisor operations behind a Unix socket.

When a template is created, Bastion boots a temporary VM, runs the ordered actions.init

steps, s it, and saves its prepared disk and VM snapshot. Creating an environment restores that snapshot, adds a small qcow2 writable overlay, runs optional actions.start

steps, and exposes SSH, OpenCode, and configured service tunnels through the API.

For multiple hosts, the optional cluster API stores shared state in Postgres, stores prepared template archives in S3-compatible object storage, schedules environments onto registered nodes, and proxies connections to the node that owns each environment.

This example prepares a Bun project once, refreshes it whenever an environment starts, and exposes its development server:

{
  "resources": {
    "vcpu": 4,
    "memory": 8,
    "volume": 40
  },
  "tunnels": {
    "web": 3000
  },
  "agents": {
    "opencode": {
      "working_directory": "/workspace/project"
    }
  },
  "actions": {
    "init": [
      {
        "use": "setup_bun"
      },
      {
        "run": "git clone https://github.com/your-org/your-repo.git project",
        "working_directory": "/workspace"
      },
      {
        "run": "bun install",
        "working_directory": "/workspace/project"
      }
    ],
    "start": [
      {
        "run": "git pull --ff-only",
        "working_directory": "/workspace/project"
      },
      {
        "run": "nohup bun run dev >/tmp/dev-server.log 2>&1 &",
        "working_directory": "/workspace/project"
      }
    ]
  }
}
bastion templates create --key project --file ./template.json
bastion env create --template-key project --key issue-123 --tag repo:project
bastion proxy --env-key issue-123 --name web

See the template guide and public JSON schema for the complete format.

  • VM hosts currently need Linux x86_64, KVM, and vhost-vsock. macOS Apple silicon is client-only. bastiond

runs as root because it manages VM lifecycle and networking operations. Template actions run as root inside the guest.- The host API binds to localhost:3148

by default. Anyone who can reach it can create, remove, and enter environments, so keep it private or place it behind your own authenticated network and TLS boundary. - OpenCode is the built-in agent integration today; SSH is available for other tools and workflows.

  • The project is pre-1.0, and interfaces may still change.

Start with the introduction and quick start, then see the guides for system setup, templates, environments, and clustering. The site also includes complete CLI and API references.

Questions, bug reports, design feedback, and use cases are welcome in GitHub Discussions or by email at hazim@bastion.computer.

Bastion is available under the MIT License.

── more in #developer-tools 4 stories · sorted by recency
── more on @bastion 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-bastion-self…] indexed:0 read:4min 2026-07-07 ·