feat(chopper): run hermes in a microvm - #120
Merged
Merged
Conversation
devusb
force-pushed
the
feat/hermes-microvm
branch
from
August 30, 2026 17:48
10a9fde to
4c4b3e3
Compare
devusb
marked this pull request as ready for review
September 5, 2026 13:14
devusb
force-pushed
the
feat/hermes-microvm
branch
4 times, most recently
from
September 5, 2026 13:53
b575f4e to
c79d011
Compare
Hermes runs from the official container image rather than the NixOS module, which upstream maintains only as a best-effort Tier 2 platform. The image gives the agent an FHS userland to install into, so third party integrations work without nix-ld shims. The guest owns its tailnet identity and reaches the dashboard over a Tailscale Service, so chopper does not proxy for it. That serve config is set imperatively and lives in tailscaled state on the guest volume: the nixpkgs module drives `serve set-config`, which registers a service as plain HTTP rather than HTTPS (tailscale/tailscale#18381). The guest is named vm-hermes so the meaningful name stays with the Tailscale Service, which is the host-independent identity. Nodes and services share a MagicDNS namespace, and a collision is resolved by a suffix that sticks even after the conflict is gone. Podman image storage and agent state get separate volumes so the image store can be reclaimed without touching memory and skills. The hermes wrapper reaches the rootful podman socket so it works without sudo.
devusb
force-pushed
the
feat/hermes-microvm
branch
from
September 5, 2026 14:27
c79d011 to
13f1974
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a
vm-hermesmicrovm guest on chopper running the official hermes-agent container image under podman. Replaces the host-native service dropped in 595c3f3.Upstream keeps the NixOS module at Tier 2 and the Docker image at Tier 1. The image ships Node, uv and Playwright, so
npx/uvxMCP servers run without thenix-ldshims the oldhermes.nixneeded.--network=host, so the dashboard binds the guest's real loopback and OAuth callback listeners need no port plumbingcontainers.imgandhermes.imgsplit podman's image store from/opt/data, which holds memory, skills and sessionshermeson PATH shells into the container via the rootful podman socket;mheltonjoins thepodmangroup so it works without sudovm-hermesso the Tailscale Service can ownsvc:hermes— nodes and services share a MagicDNS namespace, and a collision sticksServe config is set imperatively rather than from Nix:
serve set-configregisters a service as plain HTTP even when the endpoint should terminate TLS (tailscale/tailscale#18381). It persists in tailscaled state on the guest's/var/libvolume.Setup
hermes, endpointtcp:443. Must exist before a host can advertise for it.vm-hermesunder Service hosts, or:tailscale serve --service=svc:hermes --https=443 127.0.0.1:9119/opt/data/config.yaml:dashboard.public_url: "https://hermes.springhare-egret.ts.net", plus an auth provider — settingpublic_urlforces the auth gate on.hermes setup— the gateway crash-loops until it runs.Not included:
deploy-backupfor/opt/data, and declarative provider credentials.