From 582374b858a24982174b0dd0bc0ef7514422d5fb Mon Sep 17 00:00:00 2001 From: Sprite Date: Tue, 28 Apr 2026 13:27:01 +0000 Subject: [PATCH 01/18] Add Hermes Agent on Fly.io guide to blueprints Co-Authored-By: Claude Opus 4.6 (1M context) --- blueprints/hermes-agent-on-fly-io.html.md | 197 ++++++++++++++++++++++ blueprints/index.html.md | 1 + partials/_guides_nav.html.erb | 1 + 3 files changed, 199 insertions(+) create mode 100644 blueprints/hermes-agent-on-fly-io.html.md diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md new file mode 100644 index 0000000000..37944be3ee --- /dev/null +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -0,0 +1,197 @@ +--- +title: Run Hermes Agent on Fly.io +layout: docs +nav: guides +date: 2026-04-28 +--- + +[Hermes](https://github.com/NousResearch/hermes-agent) is making waves right now, mostly because its self-improvement loop is pretty nifty. Rather than expecting the user to define and install tools to accomplish repeated tasks, Hermes pays attention to its own output, notices when it had to improvise or learn by trial and error, and then automatically writes that experience into a reusable skill it can call next time. The result is: Hermes gets better at one-shotting your workflows without you writing a single prompt template. Its value and utility increase based on usage history, so you really want to be running your Hermes on a computer, not in a sandbox. + +This guide walks you through running Hermes on a Fly Machine, configuring it, and reaching its web dashboard from your laptop. + +You'll need **[flyctl](https://fly.io/docs/flyctl/install/)** installed, a **Fly.io account** ([free trial](https://fly.io/docs/about/free-trial/) works), and an **LLM API key** (Anthropic, OpenAI, Google Gemini, or [OpenRouter](https://openrouter.ai/) for access to 200+ models). + +We'll use Nous Research's **official prebuilt image** (`nousresearch/hermes-agent:latest`) so there's no Dockerfile to maintain and no remote builder to wait on; Fly pulls the image straight from Docker Hub. + +## Create the app and volume + +Hermes keeps all its state; config, API keys, sessions, skills, memories in `/opt/data` inside the container. We'll back that with a Fly volume so it persists across deploys and restarts. + +Pick an app name (must be globally unique on Fly) and a [region](https://fly.io/docs/reference/regions/) close to you, then: + +```bash +fly apps create +fly volumes create data --app --region --size 3 +``` + +3 GB is comfortable headroom for sessions and the bundled skills directory. + +## Write fly.toml + +Create a directory for the deployment config and drop a `fly.toml` in it: + +```toml +app = "" +primary_region = "" + +[build] + image = "nousresearch/hermes-agent:latest" + +[experimental] + cmd = ["gateway", "run"] + +[[mounts]] + source = "data" + destination = "/opt/data" + +[[vm]] + memory = "4gb" + cpus = 2 +``` + +A few notes: + +- **No `[build.dockerfile]`**, Fly pulls the image directly. Deploys take seconds, not minutes. +- **`[experimental] cmd = ["gateway", "run"]`** is passed to the image's entrypoint, so the machine boots into `hermes gateway run` (the messaging gateway for Telegram, Discord, Slack, WhatsApp, etc.). +- **No `[[services]]` block.** The gateway talks *outbound* to chat platforms, so you don't need a public port. The dashboard exposes API keys and shouldn't be public; we'll reach it through a Fly proxy tunnel below. +- **4 GB / 2 CPU** is the recommended size when browser tools (Playwright/Chromium) are active. If you don't use browser tools you can drop to `shared-cpu-1x` and 1–2 GB. + +## Deploy + +```bash +fly deploy --app --ha=false +``` + +`--ha=false` keeps it to a single machine; Hermes is stateful and you don't want two gateway processes writing to the same volume. + +When the deploy finishes, the machine boots, the entrypoint bootstraps `/opt/data` (creating `.env`, `config.yaml`, `SOUL.md`, `sessions/`, `skills/`, etc.), and `hermes gateway run` starts. It'll keep running but it has no API key yet, so it can't talk to a model. + +Confirm it's alive: + +```bash +fly logs --app +``` + +You should see the bundled skills sync, then the gateway starting up. + +## Configure Hermes + +SSH into the machine. The `hermes` binary lives at `/opt/hermes/.venv/bin/hermes` inside the image, but `fly ssh console` opens a login shell that resets PATH and won't find it there. Drop a symlink into `/usr/local/bin` (which is always on PATH) so `hermes` works as a bare command: + +```bash +fly ssh console --app -C \ + "ln -sf /opt/hermes/.venv/bin/hermes /usr/local/bin/hermes" +``` + +Then drop into the machine and run the setup wizard: + +```bash +fly ssh console --app +hermes setup +``` + +The wizard walks you through model selection, tool configuration, and connecting your messaging platforms. When it's done, exit the SSH session. + +Restart the machine so the gateway picks up the new config: + +```bash +fly machine restart --app +``` + +Get `` from `fly machine list --app `. + +## Web dashboard + +Hermes has a web dashboard on port 9119 for managing sessions, skills, and config. The dashboard reads your API keys, so the upstream guidance is to never expose it on a public port. Tunnel to it instead: + +In one terminal, start the dashboard inside the machine: + +```bash +fly ssh console --app -C \ + "hermes dashboard --host 127.0.0.1 --no-open" +``` + +In a second terminal, open a Fly proxy from your laptop: + +```bash +fly proxy 9119:9119 --app +``` + +Now visit `http://localhost:9119` in your browser. The traffic goes over your authenticated Fly Wireguard tunnel; nothing is published. + +When you're done, `Ctrl+C` both commands. The gateway keeps running on the machine. + +## Upgrading + +The image is stateless; your data lives on the volume. To pull the latest Hermes: + +```bash +fly deploy --app +fly ssh console --app -C \ + "ln -sf /opt/hermes/.venv/bin/hermes /usr/local/bin/hermes" +``` + +The deploy pulls `nousresearch/hermes-agent:latest` again. The second command re-creates the `/usr/local/bin/hermes` symlink; it lives on the container's filesystem, not the data volume, so each new container starts without it. + +## VM sizing + +If you're running heavy tool use or multiple concurrent sessions, scale up: + +```bash +fly scale memory 8192 --app +fly scale vm shared-cpu-4x --app +``` + +## Useful commands + +| Command | Description | +|---------|-------------| +| `fly logs --app ` | Stream live logs | +| `fly ssh console --app ` | SSH into the machine | +| `fly ssh console --app -C "hermes doctor"` | Health check | +| `fly machine restart --app ` | Restart after config changes | +| `fly status --app ` | Check machine status | +| `fly volumes list --app ` | List attached volumes | +| `fly ssh console --app -C "hermes skills list"` | List learned skills | + +## Troubleshooting + +**Gateway won't start**, check `hermes doctor` for missing API keys or other diagnostics: + +```bash +fly ssh console --app -C "hermes doctor" +``` + +**Out of memory**, increase RAM: + +```bash +fly scale memory 8192 --app +``` + +**Need to start fresh**, wipe the config files (skills, sessions, and memories survive): + +```bash +fly ssh console --app -C \ + "sh -c 'rm -f /opt/data/config.yaml /opt/data/.env'" +fly machine restart --app +fly ssh console --app +hermes setup +``` + +To wipe everything including conversations, destroy and recreate the volume: + +```bash +fly machine stop --app +fly volumes destroy --app +fly volumes create data --app --region --size 3 +fly machine start --app +``` + +**Skills behaving unexpectedly**, list, view, and delete: + +```bash +fly ssh console --app +hermes skills list +hermes skills view +hermes skills delete +``` diff --git a/blueprints/index.html.md b/blueprints/index.html.md index 68cab2e756..7565bec974 100644 --- a/blueprints/index.html.md +++ b/blueprints/index.html.md @@ -12,6 +12,7 @@ A growing library of guides for running, designing, and deploying all kinds of a Guides for the structure your app on Fly.io. Layouts, tradeoffs, moving parts. - [Deploy OpenClaw on Fly.io](/docs/blueprints/deploy-openclaw/) NEW!! +- [Run Hermes Agent on Fly.io](/docs/blueprints/hermes-agent-on-fly-io/) NEW!! - [Deploying Remote MCP Servers](/docs/blueprints/remote-mcp-servers/) - [Resilient apps use multiple Machines](/docs/blueprints/resilient-apps-multiple-machines/) - [Getting Started with N-Tier Architecture](/docs/blueprints/n-tier-architecture/) diff --git a/partials/_guides_nav.html.erb b/partials/_guides_nav.html.erb index 74047f141a..5837c74f67 100644 --- a/partials/_guides_nav.html.erb +++ b/partials/_guides_nav.html.erb @@ -15,6 +15,7 @@ open: true, links: [ { text: "Deploy OpenClaw on Fly.io", path: "/docs/blueprints/deploy-openclaw/" }, + { text: "Run Hermes Agent on Fly.io", path: "/docs/blueprints/hermes-agent-on-fly-io/" }, { text: "Deploying Remote MCP Servers", path: "/docs/blueprints/remote-mcp-servers/" }, { text: "Resilient apps use multiple Machines", path: "/docs/blueprints/resilient-apps-multiple-machines/" }, { text: "Getting Started with N-Tier Architecture", path: "/docs/blueprints/n-tier-architecture/" }, From a3574771de92a304b78e247ee66becb885681414 Mon Sep 17 00:00:00 2001 From: Daniel Botha <131688218+theoctopusperson@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:47:06 +0200 Subject: [PATCH 02/18] Update blueprints/hermes-agent-on-fly-io.html.md Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 37944be3ee..f8b6a77577 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -5,7 +5,7 @@ nav: guides date: 2026-04-28 --- -[Hermes](https://github.com/NousResearch/hermes-agent) is making waves right now, mostly because its self-improvement loop is pretty nifty. Rather than expecting the user to define and install tools to accomplish repeated tasks, Hermes pays attention to its own output, notices when it had to improvise or learn by trial and error, and then automatically writes that experience into a reusable skill it can call next time. The result is: Hermes gets better at one-shotting your workflows without you writing a single prompt template. Its value and utility increase based on usage history, so you really want to be running your Hermes on a computer, not in a sandbox. +[Hermes](https://github.com/NousResearch/hermes-agent) is an AI agent from Nous Research with a built-in learning loop: it watches its own output, notices when it had to improvise to finish a task, and writes that experience back as a reusable skill it can call next time. The skill library grows with use, so Hermes works best when it runs continuously on a persistent host rather than a short-lived sandbox, which is exactly what a Fly Machine with an attached volume gives you. This guide walks you through running Hermes on a Fly Machine, configuring it, and reaching its web dashboard from your laptop. From f623fce005664995e818a919b9fac6c3472e625c Mon Sep 17 00:00:00 2001 From: Daniel Botha <131688218+theoctopusperson@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:47:31 +0200 Subject: [PATCH 03/18] Update blueprints/hermes-agent-on-fly-io.html.md Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index f8b6a77577..854631f12f 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -108,7 +108,7 @@ In one terminal, start the dashboard inside the machine: ```bash fly ssh console --app -C \ - "hermes dashboard --host 127.0.0.1 --no-open" + "hermes dashboard --host 0.0.0.0 --no-open" ``` In a second terminal, open a Fly proxy from your laptop: From db41e46c57bb5b8e3c8fd62b40ebd54a19652643 Mon Sep 17 00:00:00 2001 From: Daniel Botha <131688218+theoctopusperson@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:47:58 +0200 Subject: [PATCH 04/18] Update blueprints/hermes-agent-on-fly-io.html.md Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 854631f12f..f28ab47966 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -117,7 +117,7 @@ In a second terminal, open a Fly proxy from your laptop: fly proxy 9119:9119 --app ``` -Now visit `http://localhost:9119` in your browser. The traffic goes over your authenticated Fly Wireguard tunnel; nothing is published. +Now visit `http://localhost:9119` in your browser. Traffic goes over your authenticated WireGuard tunnel; the dashboard isn't published to the public internet, though it is reachable from other Machines on your organization's [private network](/docs/networking/private-networking/) When you're done, `Ctrl+C` both commands. The gateway keeps running on the machine. From 963960ae04dfc8210935b5d45368f0db350b1fe5 Mon Sep 17 00:00:00 2001 From: Daniel Botha <131688218+theoctopusperson@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:49:11 +0200 Subject: [PATCH 05/18] Update blueprints/hermes-agent-on-fly-io.html.md Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index f28ab47966..142b920066 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -52,7 +52,7 @@ primary_region = "" A few notes: - **No `[build.dockerfile]`**, Fly pulls the image directly. Deploys take seconds, not minutes. -- **`[experimental] cmd = ["gateway", "run"]`** is passed to the image's entrypoint, so the machine boots into `hermes gateway run` (the messaging gateway for Telegram, Discord, Slack, WhatsApp, etc.). +- **`[processes] app = "gateway run"`** defines the single process group for this app, and its command is passed to the image's entrypoint, so the Machine boots into `hermes gateway run` (the messaging gateway for Telegram, Discord, Slack, WhatsApp, etc.). - **No `[[services]]` block.** The gateway talks *outbound* to chat platforms, so you don't need a public port. The dashboard exposes API keys and shouldn't be public; we'll reach it through a Fly proxy tunnel below. - **4 GB / 2 CPU** is the recommended size when browser tools (Playwright/Chromium) are active. If you don't use browser tools you can drop to `shared-cpu-1x` and 1–2 GB. From e7f16eb2a850c357d972b29df66f334844a5a849 Mon Sep 17 00:00:00 2001 From: Daniel Botha <131688218+theoctopusperson@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:49:33 +0200 Subject: [PATCH 06/18] Update blueprints/hermes-agent-on-fly-io.html.md Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 142b920066..e49a283cb9 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -162,7 +162,9 @@ fly scale vm shared-cpu-4x --app fly ssh console --app -C "hermes doctor" ``` -**Out of memory**, increase RAM: +**Out of memory** + +Increase RAM: ```bash fly scale memory 8192 --app From 506d443f7a3dd555cb8e7699cda3b29bac762d85 Mon Sep 17 00:00:00 2001 From: Daniel Botha <131688218+theoctopusperson@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:50:07 +0200 Subject: [PATCH 07/18] Update blueprints/hermes-agent-on-fly-io.html.md Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index e49a283cb9..d72bda90c3 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -170,7 +170,9 @@ Increase RAM: fly scale memory 8192 --app ``` -**Need to start fresh**, wipe the config files (skills, sessions, and memories survive): +**Need to start fresh** + +Wipe the config files (skills, sessions, and memories survive): ```bash fly ssh console --app -C \ From c0b2c643b89b79003a8553e6987b0260bd14a5a4 Mon Sep 17 00:00:00 2001 From: Daniel Botha <131688218+theoctopusperson@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:50:19 +0200 Subject: [PATCH 08/18] Update blueprints/hermes-agent-on-fly-io.html.md Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index d72bda90c3..c3fad24de0 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -191,7 +191,9 @@ fly volumes create data --app --region --size 3 fly machine start --app ``` -**Skills behaving unexpectedly**, list, view, and delete: +**Skills behaving unexpectedly** + +List, view, and delete: ```bash fly ssh console --app From a358d1d305aab4244edecb5bf341da4c78b4beca Mon Sep 17 00:00:00 2001 From: Daniel Botha <131688218+theoctopusperson@users.noreply.github.com> Date: Wed, 29 Apr 2026 10:50:36 +0200 Subject: [PATCH 09/18] Update blueprints/hermes-agent-on-fly-io.html.md Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index c3fad24de0..25cb1b912b 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -51,7 +51,7 @@ primary_region = "" A few notes: -- **No `[build.dockerfile]`**, Fly pulls the image directly. Deploys take seconds, not minutes. +- **No `[build.dockerfile]`.** Fly pulls the image directly. Deploys take seconds, not minutes. - **`[processes] app = "gateway run"`** defines the single process group for this app, and its command is passed to the image's entrypoint, so the Machine boots into `hermes gateway run` (the messaging gateway for Telegram, Discord, Slack, WhatsApp, etc.). - **No `[[services]]` block.** The gateway talks *outbound* to chat platforms, so you don't need a public port. The dashboard exposes API keys and shouldn't be public; we'll reach it through a Fly proxy tunnel below. - **4 GB / 2 CPU** is the recommended size when browser tools (Playwright/Chromium) are active. If you don't use browser tools you can drop to `shared-cpu-1x` and 1–2 GB. From 65aa637606420f31e2f62ac9bb7a5b8df0c5982e Mon Sep 17 00:00:00 2001 From: Daniel Botha <131688218+theoctopusperson@users.noreply.github.com> Date: Mon, 4 May 2026 11:53:00 +0200 Subject: [PATCH 10/18] Update blueprints/hermes-agent-on-fly-io.html.md Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 25cb1b912b..027e5bce4e 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -37,8 +37,8 @@ primary_region = "" [build] image = "nousresearch/hermes-agent:latest" -[experimental] - cmd = ["gateway", "run"] +[processes] + app = "gateway run" [[mounts]] source = "data" From e4447ecb9c3b1cf7332202f1dcf595927d387bf9 Mon Sep 17 00:00:00 2001 From: Daniel Botha <131688218+theoctopusperson@users.noreply.github.com> Date: Mon, 4 May 2026 11:55:35 +0200 Subject: [PATCH 11/18] Update blueprints/hermes-agent-on-fly-io.html.md Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 027e5bce4e..3db737d6e3 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -146,7 +146,7 @@ fly scale vm shared-cpu-4x --app | Command | Description | |---------|-------------| -| `fly logs --app ` | Stream live logs | +| `fly logs -a ` | Stream live logs | | `fly ssh console --app ` | SSH into the machine | | `fly ssh console --app -C "hermes doctor"` | Health check | | `fly machine restart --app ` | Restart after config changes | From 57c552812f3d46055bb5529c5739e6dbc13c0b22 Mon Sep 17 00:00:00 2001 From: theoctopusperson <131688218+theoctopusperson@users.noreply.github.com> Date: Mon, 4 May 2026 12:13:14 +0200 Subject: [PATCH 12/18] Shorten --app to -a; add header image --- blueprints/hermes-agent-on-fly-io.html.md | 62 ++++++++++++----------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 3db737d6e3..2401d1921c 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -5,6 +5,10 @@ nav: guides date: 2026-04-28 --- +
+ Illustration by Annie Ruygt of the Greek god Hermes mid-flight, depicted on a black-figure pottery bowl framed by olive branches +
+ [Hermes](https://github.com/NousResearch/hermes-agent) is an AI agent from Nous Research with a built-in learning loop: it watches its own output, notices when it had to improvise to finish a task, and writes that experience back as a reusable skill it can call next time. The skill library grows with use, so Hermes works best when it runs continuously on a persistent host rather than a short-lived sandbox, which is exactly what a Fly Machine with an attached volume gives you. This guide walks you through running Hermes on a Fly Machine, configuring it, and reaching its web dashboard from your laptop. @@ -21,7 +25,7 @@ Pick an app name (must be globally unique on Fly) and a [region](https://fly.io/ ```bash fly apps create -fly volumes create data --app --region --size 3 +fly volumes create data -a --region --size 3 ``` 3 GB is comfortable headroom for sessions and the bundled skills directory. @@ -59,7 +63,7 @@ A few notes: ## Deploy ```bash -fly deploy --app --ha=false +fly deploy -a --ha=false ``` `--ha=false` keeps it to a single machine; Hermes is stateful and you don't want two gateway processes writing to the same volume. @@ -69,7 +73,7 @@ When the deploy finishes, the machine boots, the entrypoint bootstraps `/opt/dat Confirm it's alive: ```bash -fly logs --app +fly logs -a ``` You should see the bundled skills sync, then the gateway starting up. @@ -79,14 +83,14 @@ You should see the bundled skills sync, then the gateway starting up. SSH into the machine. The `hermes` binary lives at `/opt/hermes/.venv/bin/hermes` inside the image, but `fly ssh console` opens a login shell that resets PATH and won't find it there. Drop a symlink into `/usr/local/bin` (which is always on PATH) so `hermes` works as a bare command: ```bash -fly ssh console --app -C \ +fly ssh console -a -C \ "ln -sf /opt/hermes/.venv/bin/hermes /usr/local/bin/hermes" ``` Then drop into the machine and run the setup wizard: ```bash -fly ssh console --app +fly ssh console -a hermes setup ``` @@ -95,10 +99,10 @@ The wizard walks you through model selection, tool configuration, and connecting Restart the machine so the gateway picks up the new config: ```bash -fly machine restart --app +fly machine restart -a ``` -Get `` from `fly machine list --app `. +Get `` from `fly machine list -a `. ## Web dashboard @@ -107,14 +111,14 @@ Hermes has a web dashboard on port 9119 for managing sessions, skills, and confi In one terminal, start the dashboard inside the machine: ```bash -fly ssh console --app -C \ +fly ssh console -a -C \ "hermes dashboard --host 0.0.0.0 --no-open" ``` In a second terminal, open a Fly proxy from your laptop: ```bash -fly proxy 9119:9119 --app +fly proxy 9119:9119 -a ``` Now visit `http://localhost:9119` in your browser. Traffic goes over your authenticated WireGuard tunnel; the dashboard isn't published to the public internet, though it is reachable from other Machines on your organization's [private network](/docs/networking/private-networking/) @@ -126,8 +130,8 @@ When you're done, `Ctrl+C` both commands. The gateway keeps running on the machi The image is stateless; your data lives on the volume. To pull the latest Hermes: ```bash -fly deploy --app -fly ssh console --app -C \ +fly deploy -a +fly ssh console -a -C \ "ln -sf /opt/hermes/.venv/bin/hermes /usr/local/bin/hermes" ``` @@ -138,8 +142,8 @@ The deploy pulls `nousresearch/hermes-agent:latest` again. The second command re If you're running heavy tool use or multiple concurrent sessions, scale up: ```bash -fly scale memory 8192 --app -fly scale vm shared-cpu-4x --app +fly scale memory 8192 -a +fly scale vm shared-cpu-4x -a ``` ## Useful commands @@ -147,19 +151,19 @@ fly scale vm shared-cpu-4x --app | Command | Description | |---------|-------------| | `fly logs -a ` | Stream live logs | -| `fly ssh console --app ` | SSH into the machine | -| `fly ssh console --app -C "hermes doctor"` | Health check | -| `fly machine restart --app ` | Restart after config changes | -| `fly status --app ` | Check machine status | -| `fly volumes list --app ` | List attached volumes | -| `fly ssh console --app -C "hermes skills list"` | List learned skills | +| `fly ssh console -a ` | SSH into the machine | +| `fly ssh console -a -C "hermes doctor"` | Health check | +| `fly machine restart -a ` | Restart after config changes | +| `fly status -a ` | Check machine status | +| `fly volumes list -a ` | List attached volumes | +| `fly ssh console -a -C "hermes skills list"` | List learned skills | ## Troubleshooting **Gateway won't start**, check `hermes doctor` for missing API keys or other diagnostics: ```bash -fly ssh console --app -C "hermes doctor" +fly ssh console -a -C "hermes doctor" ``` **Out of memory** @@ -167,7 +171,7 @@ fly ssh console --app -C "hermes doctor" Increase RAM: ```bash -fly scale memory 8192 --app +fly scale memory 8192 -a ``` **Need to start fresh** @@ -175,20 +179,20 @@ fly scale memory 8192 --app Wipe the config files (skills, sessions, and memories survive): ```bash -fly ssh console --app -C \ +fly ssh console -a -C \ "sh -c 'rm -f /opt/data/config.yaml /opt/data/.env'" -fly machine restart --app -fly ssh console --app +fly machine restart -a +fly ssh console -a hermes setup ``` To wipe everything including conversations, destroy and recreate the volume: ```bash -fly machine stop --app -fly volumes destroy --app -fly volumes create data --app --region --size 3 -fly machine start --app +fly machine stop -a +fly volumes destroy -a +fly volumes create data -a --region --size 3 +fly machine start -a ``` **Skills behaving unexpectedly** @@ -196,7 +200,7 @@ fly machine start --app List, view, and delete: ```bash -fly ssh console --app +fly ssh console -a hermes skills list hermes skills view hermes skills delete From 3f15b058a4bbe5aa79d1101bf7f5beb96f705dcc Mon Sep 17 00:00:00 2001 From: Kristin Martin Date: Mon, 4 May 2026 08:44:56 -0700 Subject: [PATCH 13/18] Apply suggestion from @kcmartin --- blueprints/hermes-agent-on-fly-io.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 2401d1921c..2c270f5cbd 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -80,7 +80,7 @@ You should see the bundled skills sync, then the gateway starting up. ## Configure Hermes -SSH into the machine. The `hermes` binary lives at `/opt/hermes/.venv/bin/hermes` inside the image, but `fly ssh console` opens a login shell that resets PATH and won't find it there. Drop a symlink into `/usr/local/bin` (which is always on PATH) so `hermes` works as a bare command: +SSH into the machine. The `hermes` binary lives at `/opt/hermes/.venv/bin/hermes` inside the image, but `fly ssh console` opens a login shell that resets PATH and won't find it there. Add a symlink into `/usr/local/bin` (which is always on PATH) so `hermes` works as a bare command: ```bash fly ssh console -a -C \ From 05f6df8c627c7ba2be839962ab5a8fd12de43163 Mon Sep 17 00:00:00 2001 From: Kristin Martin Date: Mon, 4 May 2026 08:45:52 -0700 Subject: [PATCH 14/18] Apply suggestion from @kcmartin --- blueprints/hermes-agent-on-fly-io.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 2c270f5cbd..5fcb56950c 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -87,7 +87,7 @@ fly ssh console -a -C \ "ln -sf /opt/hermes/.venv/bin/hermes /usr/local/bin/hermes" ``` -Then drop into the machine and run the setup wizard: +Then open a shell on the machine and run the setup wizard: ```bash fly ssh console -a From 99fa7a75768a501ac0b1035be0670bfcc12b276c Mon Sep 17 00:00:00 2001 From: Kristin Martin Date: Mon, 4 May 2026 08:46:35 -0700 Subject: [PATCH 15/18] Apply suggestion from @kcmartin --- blueprints/hermes-agent-on-fly-io.html.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 5fcb56950c..d998d973ef 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -160,7 +160,9 @@ fly scale vm shared-cpu-4x -a ## Troubleshooting -**Gateway won't start**, check `hermes doctor` for missing API keys or other diagnostics: +**Gateway won't start** + +Check `hermes doctor` for missing API keys or other diagnostics: ```bash fly ssh console -a -C "hermes doctor" From d68754eadb969bd8f782dc1fc1fb234f196455a8 Mon Sep 17 00:00:00 2001 From: Kristin Martin Date: Mon, 4 May 2026 08:51:05 -0700 Subject: [PATCH 16/18] Change we to you for consistency Co-authored-by: Kristin Martin --- blueprints/hermes-agent-on-fly-io.html.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index d998d973ef..63ff7ab143 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -19,7 +19,7 @@ We'll use Nous Research's **official prebuilt image** (`nousresearch/hermes-agen ## Create the app and volume -Hermes keeps all its state; config, API keys, sessions, skills, memories in `/opt/data` inside the container. We'll back that with a Fly volume so it persists across deploys and restarts. +Hermes keeps all its state in `/opt/data` inside the container. That includes config, API keys, sessions, skills, and memories. You'll back that with a Fly volume so it persists across deploys and restarts. Pick an app name (must be globally unique on Fly) and a [region](https://fly.io/docs/reference/regions/) close to you, then: @@ -57,7 +57,7 @@ A few notes: - **No `[build.dockerfile]`.** Fly pulls the image directly. Deploys take seconds, not minutes. - **`[processes] app = "gateway run"`** defines the single process group for this app, and its command is passed to the image's entrypoint, so the Machine boots into `hermes gateway run` (the messaging gateway for Telegram, Discord, Slack, WhatsApp, etc.). -- **No `[[services]]` block.** The gateway talks *outbound* to chat platforms, so you don't need a public port. The dashboard exposes API keys and shouldn't be public; we'll reach it through a Fly proxy tunnel below. +- **No `[[services]]` block.** The gateway talks *outbound* to chat platforms, so you don't need a public port. The dashboard exposes API keys and shouldn't be public; you'll reach it through a Fly proxy tunnel below. - **4 GB / 2 CPU** is the recommended size when browser tools (Playwright/Chromium) are active. If you don't use browser tools you can drop to `shared-cpu-1x` and 1–2 GB. ## Deploy From fc8579f888d69d78d62118ba031c56484dbfc5b9 Mon Sep 17 00:00:00 2001 From: Kristin Martin Date: Mon, 4 May 2026 08:52:49 -0700 Subject: [PATCH 17/18] change we to you to match the rest of the guide --- blueprints/hermes-agent-on-fly-io.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 63ff7ab143..7f7711d01a 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -15,7 +15,7 @@ This guide walks you through running Hermes on a Fly Machine, configuring it, an You'll need **[flyctl](https://fly.io/docs/flyctl/install/)** installed, a **Fly.io account** ([free trial](https://fly.io/docs/about/free-trial/) works), and an **LLM API key** (Anthropic, OpenAI, Google Gemini, or [OpenRouter](https://openrouter.ai/) for access to 200+ models). -We'll use Nous Research's **official prebuilt image** (`nousresearch/hermes-agent:latest`) so there's no Dockerfile to maintain and no remote builder to wait on; Fly pulls the image straight from Docker Hub. +You'll use Nous Research's **official prebuilt image** (`nousresearch/hermes-agent:latest`) so there's no Dockerfile to maintain and no remote builder to wait on. Fly pulls the image straight from Docker Hub. ## Create the app and volume From 9d67eb9d81baf32344414d841385c9aa9324cbbd Mon Sep 17 00:00:00 2001 From: Kristin Martin Date: Mon, 4 May 2026 09:38:08 -0700 Subject: [PATCH 18/18] fix image filename and change docs links to relative --- blueprints/hermes-agent-on-fly-io.html.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/blueprints/hermes-agent-on-fly-io.html.md b/blueprints/hermes-agent-on-fly-io.html.md index 7f7711d01a..7050ee416b 100644 --- a/blueprints/hermes-agent-on-fly-io.html.md +++ b/blueprints/hermes-agent-on-fly-io.html.md @@ -2,18 +2,18 @@ title: Run Hermes Agent on Fly.io layout: docs nav: guides -date: 2026-04-28 +date: 2026-05-04 ---
- Illustration by Annie Ruygt of the Greek god Hermes mid-flight, depicted on a black-figure pottery bowl framed by olive branches + Illustration by Annie Ruygt of the Greek god Hermes mid-flight, depicted on a black-figure pottery bowl framed by olive branches
[Hermes](https://github.com/NousResearch/hermes-agent) is an AI agent from Nous Research with a built-in learning loop: it watches its own output, notices when it had to improvise to finish a task, and writes that experience back as a reusable skill it can call next time. The skill library grows with use, so Hermes works best when it runs continuously on a persistent host rather than a short-lived sandbox, which is exactly what a Fly Machine with an attached volume gives you. This guide walks you through running Hermes on a Fly Machine, configuring it, and reaching its web dashboard from your laptop. -You'll need **[flyctl](https://fly.io/docs/flyctl/install/)** installed, a **Fly.io account** ([free trial](https://fly.io/docs/about/free-trial/) works), and an **LLM API key** (Anthropic, OpenAI, Google Gemini, or [OpenRouter](https://openrouter.ai/) for access to 200+ models). +You'll need **[flyctl](/docs/flyctl/install/)** installed, a **Fly.io account** ([free trial](/docs/about/free-trial/) works), and an **LLM API key** (Anthropic, OpenAI, Google Gemini, or [OpenRouter](https://openrouter.ai/) for access to 200+ models). You'll use Nous Research's **official prebuilt image** (`nousresearch/hermes-agent:latest`) so there's no Dockerfile to maintain and no remote builder to wait on. Fly pulls the image straight from Docker Hub. @@ -21,7 +21,7 @@ You'll use Nous Research's **official prebuilt image** (`nousresearch/hermes-age Hermes keeps all its state in `/opt/data` inside the container. That includes config, API keys, sessions, skills, and memories. You'll back that with a Fly volume so it persists across deploys and restarts. -Pick an app name (must be globally unique on Fly) and a [region](https://fly.io/docs/reference/regions/) close to you, then: +Pick an app name (must be globally unique on Fly) and a [region](/docs/reference/regions/) close to you, then: ```bash fly apps create