May 21May 21 Hermes Agent on Unraid — Complete Install Guide (v0.14.0, Built from Hard-Won Experience)PrerequisitesUnraid 6.12+Docker enabledAn SSD or NVMe pool mounted (e.g., /mnt/cache/ or /mnt/ssd/) — not an array disk via /mnt/user/An Ollama container already running and accessible on your LANAt least one Ollama model with native context ≥ 64K (gemma4, qwen 3.6, llama 3.x, etc.)Optional: a Telegram bot token from @BotFather and your numeric user ID from @userinfobotPhase 1 — Prep Ollama ProperlyBefore Hermes touches anything, make sure Ollama is configured for agent work.Edit your Ollama container templateAdd these environment variables (or update them if they exist):KeyValuePurposeOLLAMA_HOST0.0.0.0:11434Reachable from other containersOLLAMA_CONTEXT_LENGTH65536Agent workloads need 64K+OLLAMA_KEEP_ALIVE24hKeep model warm in VRAMOLLAMA_FLASH_ATTENTION1Faster, less VRAMOLLAMA_NUM_PARALLEL2Allow concurrent requestsOLLAMA_MAX_LOADED_MODELS2Main model + optional auxOLLAMA_SCHED_SPREAD1 (optional)Force multi-GPU split (only if needed)Apply. Verify with:docker exec ollama printenv | grep OLLAMAdocker exec ollama nvidia-smiBoth GPUs should be visible.Pick and prepare a modelRun:docker exec ollama ollama listPick one with native context ≥ 64K. Verify:docker exec ollama ollama show <model-name> | grep -i "context length"If the number is ≥ 65536, you're set. If lower, pick a different model or create a derived Modelfile.Phase 2 — Prepare the Appdata DirectoryThis is the single biggest source of failure later. Get it right now.Critical: use a direct pool path, NOT /mnt/user/The FUSE-based /mnt/user/ filesystem breaks SQLite locking. Always use the direct pool mount.in console:mkdir -p /mnt/cache/appdata/hermes-agent(Replace /mnt/cache/ with /mnt/ssd/ or whichever pool you use for appdata.)Do NOT chown to 99:100The Hermes image expects UID 10000 internally. Match that:in console:chown -R 10000:10000 /mnt/cache/appdata/hermes-agentPhase 3 — Run the Setup Wizard (Carefully)Pull the image and run the wizarddocker run -it --rm \ -v /mnt/cache/appdata/hermes-agent:/opt/data \ nousresearch/hermes-agent setupWizard answers — exact valuesModel provider: Choose Custom Endpoint (enter URL manually) — NOT "Custom Direct API."API base URL: http://<your-unraid-ip>:11434/v1 (e.g., http://10.10.10.150:11434/v1 — the /v1 is required, OpenAI-compat path)API key: ollama (any non-empty string — Ollama doesn't validate it)Model name: Exact tag from ollama list, e.g., gemma4:26bContext length: 65536⚠️ Critical typing rule: Do NOT press the up arrow during text input. The wizard captures the literal \e[A escape sequence and corrupts the value. If you mistype, use Backspace, never arrow keys.Configure aux models: Skip / use main provider for everything. Adding aux models with mismatched context windows causes silent failures.Telegram setup (optional):Bot token: paste the full <numeric>:<alphanumeric> from BotFather (40+ chars). If you only have a placeholder, skip this step rather than entering junk.Allowed users: paste your numeric Telegram user ID from @userinfobot. Never leave empty — "open access" means anyone with your bot username can burn your tokens.Agent name / SOUL: accept defaults.⚠️ Critical: NEVER Ctrl+C the wizardThe wizard atomic-commits at the end. Ctrl+C = lost configuration. If a step asks something you don't have an answer for, enter a placeholder (e.g., none, skip) and edit the file afterward. Always let the wizard run to completion.Verify what the wizard wrotecat /mnt/cache/appdata/hermes-agent/config.yaml | head -10grep -E "TELEGRAM|HERMES" /mnt/cache/appdata/hermes-agent/.envThe config.yaml should have a clean model: block. The .env should have your Telegram credentials if you set them up.Phase 4 — Build the Unraid Docker TemplateSwitch to Advanced View in the top-right toggle of the Add Container page. Without this, you can't add Post Arguments or Extra Parameters.Top sectionFieldValueNamehermes-agentRepositorynousresearch/hermes-agent:latestNetwork TypeBridgeConsole shell commandBashPrivilegedOffPost Argumentsgateway runExtra Parameters--restart=unless-stopped --shm-size=1g --memory=8gIcon URL (optional)https://avatars.githubusercontent.com/u/134168893?s=200WebUIhttp://[IP]:[PORT:9119]/Ports — add BOTH at onceGateway API:FieldValueConfig TypePortNameGateway APIContainer Port8642Host Port8642Default Value8642Connection TypeTCPWeb Dashboard:FieldValueConfig TypePortNameWeb DashboardContainer Port9119Host Port9119Default Value9119Connection TypeTCPPath (just one)FieldValueConfig TypePathNameConfig and DataContainer Path/opt/dataHost Path/mnt/cache/appdata/hermes-agentDefault Value/mnt/cache/appdata/hermes-agentAccess ModeRead/Write⚠️ Use the direct pool path (/mnt/cache/ or /mnt/ssd/), never /mnt/user/.Environment Variables — exactly these, nothing extraDashboard:KeyValueNotesHERMES_DASHBOARD1Enable web dashboardHERMES_DASHBOARD_HOST0.0.0.0LAN-accessibleHERMES_DASHBOARD_PORT9119Match the port mappingHERMES_DASHBOARD_TUI1In-browser Chat tabAPI server:KeyValueNotesAPI_SERVER_ENABLEDtrueOpenAI-compat API on 8642API_SERVER_HOST0.0.0.0LAN-accessibleAPI_SERVER_KEY(generate)See belowAPI_SERVER_CORS_ORIGINS*Allow browser appsGenerate API key once:openssl rand -hex 32Paste that into the API_SERVER_KEY field.Local model tuning:KeyValueNotesHERMES_STREAM_READ_TIMEOUT180030 min timeout for slow local inferenceTZAmerica/New_YorkYour timezoneClick ApplyThe container will pull the image (~2 GB) if not already cached, then start.Phase 5 — First Boot VerificationWatch the startup logsdocker logs -f hermes-agentWhat you should see (in order):Fixing ownership of /opt/data to hermes (10000)Syncing bundled skills into ~/.hermes/skills/ ...Done: 87 new, 0 updated, 0 unchanged. 87 total bundled. (first run) or 0 new, 0 updated, 87 unchanged (subsequent)Starting hermes dashboard on 0.0.0.0:9119 (background)[dashboard] Hermes Web UI → http://0.0.0.0:9119The gateway bannerNo errors — specifically:❌ No esbuild permission denied❌ No database is locked❌ No YAML parse errors❌ No SIGTERM restart loops❌ No "No user allowlists configured" (if you set up Telegram)Ctrl+C to stop tailing once it settles.Verify ports are mappeddocker port hermes-agentExpected:8642/tcp -> 0.0.0.0:86429119/tcp -> 0.0.0.0:9119Open the dashboardBrowser → http://<your-unraid-ip>:9119You should see:Status page showing gateway running and versionChat tab in the sidebar (the in-browser TUI is working)Config tab with your model and context settings populatedLogs tab populatingPhase 6 — Smoke Test the Full StackTest via the GUI Chat tabSend: "hello, what model are you running?"Should reply with model name and respond cleanly. If it errors with "context window below minimum 64,000," your config.yaml has the wrong context_length — go to Config tab and verify it's 65536.Test tool use via Telegram (if configured)Send to your bot: "Run ls -la in the workspace and tell me what's there"Should:Acknowledge the requestRun the toolReply with file listingWhile it runs, in terminal:docker exec ollama ollama psdocker exec ollama nvidia-smiExpected:ollama ps shows your model loaded with CONTEXT 65536, 100% GPUnvidia-smi shows ~22-24 GB VRAM in use, your model's process listedSet Telegram home channelIn your Telegram chat with the bot, send: /sethomeThis lets Hermes deliver scheduled task results and cross-platform messages to that chat.Troubleshooting Quick ReferenceSymptomLikely CauseFixERR_CONNECTION_REFUSED on :9119Port not mapped or dashboard crashedVerify docker port hermes-agent shows 9119; check logs for [dashboard] errorsContainer restart-loops with esbuild errorWrong UID — directory permissionsRe-chown appdata to 10000:10000, remove HERMES_UID/HERMES_GID env vars"database is locked" warningAppdata on /mnt/user/ FUSEMove appdata to /mnt/cache/ or /mnt/ssd/ direct pool pathYAML parse error line 3 column 6Hidden characters or \e[A from arrow keys in wizardDelete config.yaml, re-run wizard, type carefully"context window 32,768 below minimum 64,000"context_length in config.yaml too lowDashboard → Config → General → set to 65536Telegram bot doesn't respondMissing TELEGRAM_ALLOWED_USERS in .envAdd TELEGRAM_ALLOWED_USERS=<your_id> to .env, restart containerModel loaded but only on one GPUWorking as designed (fits on one card)Add OLLAMA_SCHED_SPREAD=1 to Ollama if you want forced splitWizard "leave empty for open access" promptDon't!Always set explicit allowlist on Telegram/Discord/SlackOptional ImprovementsOnce everything works, these polish steps are worth doing:Add a fallback provider in config.yaml for when local inference is unavailableInstall Chrome/Playwright inside the container for browser_navigate toolConfigure cron jobs in the dashboard for scheduled agent tasksBump container memory to 16 GB if you'll do heavy multi-turn agent workSave the Unraid template as a Community Apps XML so you can rebuild quicklySummary of Lessons LearnedThe four mistakes we made and what to remember:UID matters more than Unraid conventions. I had you set HERMES_UID=99 to match Unraid's "nobody" — but the image's pre-built /opt/hermes/ is owned by UID 10000. The mismatch killed the dashboard TUI build. Don't fight the image — use UID 10000 and chown appdata to match./mnt/user/ is not safe for SQLite-using containers. Always use the direct pool path. This applies to every Docker container on Unraid with a database (Plex, *arr stack, Nextcloud, Hermes, etc.).The wizard atomic-commits. Ctrl+C loses everything. If you don't have a value for a prompt, enter a placeholder rather than aborting.Hermes' context check reads YOUR config, not the model's max. The 32K error wasn't a model limitation — it was the value we wrote in config.yaml. Always set context_length ≥ 65536 for any model that natively supports it.Follow this guide top to bottom and you'll have a working Hermes Agent on Unraid in 20 minutes instead of 4 hours. Save it somewhere — you may want to rebuild someday.I am not an expert, I know a decent amount but I used Opus 4.7 to add a custom docker and install the latest hermes because I could not find a docker in the app store that had the latest.. of course they will probably be one there in the next hour :) Hope this helps someone. Edited May 21May 21 by Renew
May 21May 21 Hello thanks for the post I have 1 question why not use the official hermes app instead? what is the benefit of doing this way ?
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.