How to install Hermes Agent on a Linux server (or with Docker)
Nous's installer and what it leaves, a model, the gateway as a service, the dashboard, Docker, and the default that borrows Claude Code's and Codex's logins.
On a Linux server, run Nous Research’s installer as the user Hermes will run as, not with sudo, then point it at a model and start its gateway as a service:
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash -s -- --non-interactive
source ~/.bashrc
hermes config set OPENROUTER_API_KEY sk-or-...
hermes config set auth.adopt_external_logins false
hermes gateway install
sudo loginctl enable-linger $USERThe fourth line matters if Claude Code or Codex is on the same machine: by default Hermes borrows their sign-ins when it has none of its own, and Nous’s docs warn that the two programs then sign each other out. The installer follows Hermes’s development branch, not a release; if you want a pinned release, Nous’s Docker image is the route.
Before you start
Linux and WSL2 on x86_64 or ARM64 are Nous’s first-tier platforms, alongside Docker: “We test on the latest Ubuntu and WSL2.” The script needs Git, curl, tar and a SHA-256 tool, and brings everything else itself: a pinned Python 3.14, Node.js, npm, ripgrep, FFmpeg, and by default a browser for its web tools. On minimal Debian, Ubuntu or RHEL images it also needs one system library, libatomic: an interactive run asks for your sudo password once to install it, but a --non-interactive run never prompts, so on such an image install it first (sudo apt install libatomic1 on Debian or Ubuntu). Nous gives no memory or disk figure for this install; its docs say “A $5/month VPS is plenty for running the gateway,” while its Docker page asks for at least 2 GB of memory once the browser tools are in use, which the installer adds unless you pass --skip-browser. The model needs a context window of at least 64,000 tokens, or Hermes refuses it at startup.
Run the installer as the account Hermes will live under. “Don’t use sudo with the installer — it installs to ~/.local/bin,” and the security checklist says to “never run the gateway as root.”
The installer, and what it leaves
The one-liner on Nous’s installation page is curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash. Run that way in a terminal, it walks you through setup at the end. On a server you script, pass --non-interactive after bash -s --, as above; it skips the wizard and the gateway step, which you then do with the commands below. The other flags worth knowing are --skip-browser and --skip-computer-use, which Hermes remembers on later updates.
It installs the source into ~/.hermes/hermes-agent/, a hermes command in ~/.local/bin, and your data, settings and keys in ~/.hermes/ (config.yaml for settings, .env for keys). It adds a guarded line putting ~/.local/bin on your PATH to your shell’s start-up files, skipping any file that already does. On an Ubuntu 24.04 server on October 9, 2026, the non-interactive install took 110 seconds, left 2.9 GB in ~/.hermes, added the line to .bashrc and left .profile, which already put ~/.local/bin on the PATH, alone; hermes doctor then passed.
The install is not a release. The script’s branch is main, and Nous’s updating page says “Source installs track main, the only valid source channel.” On October 9, a day after the v0.21.6 release, main was already 305 commits past it, and three installs made the same day reported v0.21.6+199, +245 and +288: two installs a few hours apart are not the same Hermes.
Connecting a model
The setup wizard (hermes setup) does this interactively. Without a terminal it doesn’t: Nous’s CLI reference says --non-interactive uses “defaults / environment values”, but in practice it prints advice and stops. The route that works unattended is hermes config set, which puts each value in the right file by its shape: “Dotted paths go to config.yaml; every UPPER_SNAKE name (OPENROUTER_API_KEY, ...) is an environment variable and goes to .env.” So hermes config set OPENROUTER_API_KEY sk-or-... and hermes config set model anthropic/claude-opus-4.6. From a terminal you can use, hermes model is the command for adding providers and running sign-ins; inside a chat, /model only switches between ones already set up.
- An API key (OpenRouter, Anthropic, OpenAI and others) is the plainest route and bills per token.
- A ChatGPT plan goes in through
hermes model, then ChatGPT or Codex Subscription, which uses a device code by default, so it works over SSH. Nous says which plans qualify and how the usage counts are “not currently documented”. - A Claude account is narrower than it looks: “It only works if you’re on a Claude Max plan and have purchased extra usage credits. The base Max plan allowance ... is not consumed by Hermes — only the extra/overage credits you’ve added on top are. Claude Pro subscribers cannot use this path.”
If Claude Code or Codex runs on the same machine
Hermes has a setting, auth.adopt_external_logins, that is on by default. In Nous’s security docs: “When Hermes has no usable login of its own for openai-codex or anthropic, it can borrow the Codex CLI’s ~/.codex/auth.json and Claude Code’s ~/.claude/.credentials.json (or Keychain entry) and refresh them on your behalf.” The catch follows: “Both use single-use, rotating refresh tokens: once two programs hold one token family, whichever refreshes first invalidates the other’s copy, which shows up as ‘I logged in once in the terminal and Hermes keeps failing’ (or the reverse).” Their advice for a machine that runs those tools: “give Hermes its own login and turn adoption off.”
We saw the default at work on October 9. With the setting on and Hermes pointed at Anthropic with no key of its own, Hermes took the token in Claude Code’s login file and sent it to Anthropic as its credential, without asking. With hermes config set auth.adopt_external_logins false (which hermes config get then read back as false), the same request stopped at “No Anthropic credentials found”, and hermes auth list said external logins are not adopted. The docs add two things: in hermes model, a detected Claude Code login is offered first, with “Use existing credentials” selected; and Hermes’s own tools run with your real home folder by default, so commands it runs can find whatever sign-ins your shell can (terminal.home_mode: profile gives each Hermes profile its own).
The gateway, as a service
The gateway is the part that keeps Hermes reachable from Telegram, Discord, Slack and the rest. hermes gateway install writes a systemd user unit named hermes-gateway and starts it; logs are in journalctl --user -u hermes-gateway -f. A user unit stops when you log out unless lingering is on, hence sudo loginctl enable-linger $USER. In our run the service came up and opened no network port. Nous’s messaging page gives both choices for a server, a little at odds with itself: “Use the system service on VPS or headless hosts” (sudo hermes gateway install --system), and, further down, “For a headless VM you never log into, a user service with lingering enabled gives you the same start-at-boot behavior with zero root involvement”, the second also sparing a root prompt on every update’s restart. By default the gateway answers nobody until you allow a user or pair one; never set GATEWAY_ALLOW_ALL_USERS=true on a server that matters.
The dashboard, kept private
hermes dashboard serves Hermes’s web admin on 127.0.0.1:9119. Bind it to anything else and it requires a sign-in method, or refuses to start. Nous removed the old --insecure bypass after what its Docker page calls the June 2026 campaign: “internet scanners reached exposed dashboards (and OpenAI API servers) and drove the agent into planting an SSH-key backdoor.” Its advice for an admin page with no login: “bind to 127.0.0.1 and reach it over an SSH tunnel or Tailscale.” From a laptop that is ssh -L 9119:127.0.0.1:9119 you@server and then http://localhost:9119. The built-in username-and-password option is, in Nous’s words, for “a trusted network or behind a VPN — not for public-internet exposure.”
The Docker route
Docker is the other first-tier install, and the one that gives you a fixed version. From Nous’s Docker page, the setup run and then the gateway:
mkdir -p ~/.hermes
docker run -it --rm -v ~/.hermes:/opt/data nousresearch/hermes-agent setup
docker run -d --name hermes --restart unless-stopped \
-v ~/.hermes:/opt/data nousresearch/hermes-agent gateway runEverything Hermes keeps lives in the /opt/data volume, the image itself runs as a non-root user, and hermes update inside it refuses and tells you to pull a new image instead. The docs’ example also publishes port 8642, which only the dashboard and outside tools need; on an internet-facing machine, leave it off or bind it to localhost, since “Opening any port on an internet facing machine is a security risk.” On tags, the docs and Docker Hub disagree: the docs describe latest/stable, main and versioned X.Y.Z tags, while on October 9 the versioned tag was v0.21.6, with a v, and stable pointed at a different image from it. For a deployment that must not move, Nous’s own advice is to pin by digest.
Updating, and checking it
hermes update pulls the newest main, prepares its dependencies and restarts the gateways it stopped; “Your bots are offline for that window,” and it saves your settings, keys and pairing data first. hermes update --check only looks. hermes doctor reports what is missing or broken and exits non-zero while anything is, and hermes uninstall --dry-run shows what removal would take; your ~/.hermes data is kept unless you ask otherwise. Hermes released 37 versions between March and October 2026, a median of five days apart, so how often you update is a real decision on a machine others rely on.