{"repo":"NousResearch/hermes-agent","public_id":"850","display_label":"Docker container support for Hermes Agent","summary":"These issues and pull requests concern adding Docker container and image support for running the Hermes Agent. The work includes creating Dockerfiles and enabling full Docker-based deployment.","subsystem":"agent","counts":{"members":4,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":2},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":3668,"merged_at":"2026-03-29T05:21:48+00:00"},"resolution":{"state":"resolved","by":"pr-3668"},"freshness":{"state":"stale","last_verified_at":"2026-03-29T05:21:48+00:00","is_stale":true},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.5},"fix_edges":[{"issue_number":850,"pr_number":3668,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-03-29T05:21:48+00:00"}],"members":[{"kind":"issue","number":850,"title":"[Feature]: Full docker deployment","url":null,"state":"closed"},{"kind":"pr","number":1841,"title":"Add a docker container for the agent","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#3668","number":3668},{"kind":"pr","value":"#3610","number":3610}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":3637,"title":"feat: add Docker image for running Hermes Agent in containers","url":null,"state":"closed","close_reason":{"category":"superseded_by_pr","implication":"superseded"},"merged":false},{"kind":"pr","number":3668,"title":"feat(docker): add Docker container for the agent (salvage #1841)","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":[".dockerignore",".github/workflows/docker-publish.yml","Dockerfile","docker/SOUL.md","docker/entrypoint.sh","website/docs/user-guide/docker.md","website/sidebars.ts"],"fix_hunks":[{"file":".dockerignore","hunks":["@@ -0,0 +1,13 @@\n+# Git\n+.git\n+.gitignore\n+.gitmodules\n+\n+# Dependencies\n+node_modules\n+\n+# CI/CD\n+.github\n+\n+# Environment files\n+.env\n\\ No newline at end of file"]},{"file":".github/workflows/docker-publish.yml","hunks":["@@ -0,0 +1,61 @@\n+name: Docker Build and Publish\n+\n+on:\n+  push:\n+    branches: [main]\n+  pull_request:\n+    branches: [main]\n+\n+concurrency:\n+  group: docker-${{ github.ref }}\n+  cancel-in-progress: true\n+\n+jobs:\n+  build-and-push:\n+    runs-on: ubuntu-latest\n+    timeout-minutes: 30\n+    steps:\n+      - name: Checkout code\n+        uses: actions/checkout@v4\n+        with:\n+          submodules: recursive\n+\n+      - name: Set up Docker Buildx\n+        uses: docker/setup-buildx-action@v3\n+\n+      - name: Build image\n+        uses: docker/build-push-action@v6\n+        with:\n+          context: .\n+          file: Dockerfile\n+          load: true\n+          tags: nousresearch/hermes-agent:test\n+          cache-from: type=gha\n+          cache-to: type=gha,mode=max\n+\n+      - name: Test image starts\n+        run: |\n+          docker run --rm \\\n+            -v /tmp/hermes-test:/opt/data \\\n+            --entrypoint /opt/hermes/docker/entrypoint.sh \\\n+            nousresearch/hermes-agent:test --help\n+\n+      - name: Log in to Docker Hub\n+        if: github.event_name == 'push' && github.ref == 'refs/heads/main'\n+        uses: docker/login-action@v3\n+        with:\n+          username: ${{ secrets.DOCKERHUB_USERNAME }}\n+          password: ${{ secrets.DOCKERHUB_TOKEN }}\n+\n+      - name: Push image\n+        if: github.event_name == 'push' && github.ref == 'refs/heads/main'\n+        uses: docker/build-push-action@v6\n+        with:\n+          context: .\n+          file: Dockerfile\n+          push: true\n+          tags: |\n+            nousresearch/hermes-agent:latest\n+            nousresearch/hermes-agent:${{ github.sha }}\n+          cache-from: type=gha\n+          cache-to: type=gha,mode=max"]},{"file":"Dockerfile","hunks":["@@ -0,0 +1,20 @@\n+FROM debian:13.4\n+\n+RUN apt-get update\n+RUN apt-get install -y nodejs npm python3 python3-pip ripgrep ffmpeg gcc python3-dev libffi-dev\n+\n+COPY . /opt/hermes\n+WORKDIR /opt/hermes\n+\n+RUN pip install -e \".[all]\" --break-system-packages\n+RUN npm install\n+RUN npx playwright install --with-deps chromium\n+WORKDIR /opt/hermes/scripts/whatsapp-bridge\n+RUN npm install\n+\n+WORKDIR /opt/hermes\n+RUN chmod +x /opt/hermes/docker/entrypoint.sh\n+\n+ENV HERMES_HOME=/opt/data\n+VOLUME [ \"/opt/data\" ]\n+ENTRYPOINT [ \"/opt/hermes/docker/entrypoint.sh\" ]\n\\ No newline at end of file"]},{"file":"docker/SOUL.md","hunks":["@@ -0,0 +1,15 @@\n+# Hermes Agent Persona\n+\n+<!--\n+This file defines the agent's personality and tone.\n+The agent will embody whatever you write here.\n+Edit this to customize how Hermes communicates with you.\n+\n+Examples:\n+  - \"You are a warm, playful assistant who uses kaomoji occasionally.\"\n+  - \"You are a concise technical expert. No fluff, just facts.\"\n+  - \"You speak like a friendly coworker who happens to know everything.\"\n+\n+This file is loaded fresh each message -- no restart needed.\n+Delete the contents (or this file) to use the default personality.\n+-->\n\\ No newline at end of file"]},{"file":"docker/entrypoint.sh","hunks":["@@ -0,0 +1,34 @@\n+#!/bin/bash\n+# Docker entrypoint: bootstrap config files into the mounted volume, then run hermes.\n+set -e\n+\n+HERMES_HOME=\"/opt/data\"\n+INSTALL_DIR=\"/opt/hermes\"\n+\n+# Create essential directory structure.  Cache and platform directories\n+# (cache/images, cache/audio, platforms/whatsapp, etc.) are created on\n+# demand by the application — don't pre-create them here so new installs\n+# get the consolidated layout from get_hermes_dir().\n+mkdir -p \"$HERMES_HOME\"/{cron,sessions,logs,hooks,memories,skills}\n+\n+# .env\n+if [ ! -f \"$HERMES_HOME/.env\" ]; then\n+    cp \"$INSTALL_DIR/.env.example\" \"$HERMES_HOME/.env\"\n+fi\n+\n+# config.yaml\n+if [ ! -f \"$HERMES_HOME/config.yaml\" ]; then\n+    cp \"$INSTALL_DIR/cli-config.yaml.example\" \"$HERMES_HOME/config.yaml\"\n+fi\n+\n+# SOUL.md\n+if [ ! -f \"$HERMES_HOME/SOUL.md\" ]; then\n+    cp \"$INSTALL_DIR/docker/SOUL.md\" \"$HERMES_HOME/SOUL.md\"\n+fi\n+\n+# Sync bundled skills (manifest-based so user edits are preserved)\n+if [ -d \"$INSTALL_DIR/skills\" ]; then\n+    python3 \"$INSTALL_DIR/tools/skills_sync.py\"\n+fi\n+\n+exec hermes \"$@\""]},{"file":"website/docs/user-guide/docker.md","hunks":["@@ -0,0 +1,56 @@\n+# Hermes Agent — Docker\n+\n+Want to run Hermes Agent, but without installing packages on your host? This'll sort you out.\n+\n+This will let you run the agent in a container, with the most relevant modes outlined below.\n+\n+The container stores all user data (config, API keys, sessions, skills, memories) in a single directory mounted from the host at `/opt/data`. The image itself is stateless and can be upgraded by pulling a new version without losing any configuration.\n+\n+## Quick start\n+\n+If this is your first time running Hermes Agent, create a data directory on the host and start the container interactively to run the setup wizard:\n+\n+```sh\n+mkdir -p ~/.hermes\n+docker run -it --rm \\\n+  -v ~/.hermes:/opt/data \\\n+  nousresearch/hermes-agent\n+```\n+\n+This drops you into the setup wizard, which will prompt you for your API keys and write them to `~/.hermes/.env`. You only need to do this once. It is highly recommended to set up a chat system for the gateway to work with at this point.\n+\n+## Running in gateway mode\n+\n+Once configured, run the container in the background as a persistent gateway (Telegram, Discord, Slack, WhatsApp, etc.):\n+\n+```sh\n+docker run -d \\\n+  --name hermes \\\n+  --restart unless-stopped \\\n+  -v ~/.hermes:/opt/data \\\n+  nousresearch/hermes-agent gateway run\n+```\n+\n+## Running interactively (CLI chat)\n+\n+To open an interactive chat session against a running data directory:\n+\n+```sh\n+docker run -it --rm \\\n+  -v ~/.hermes:/opt/data \\\n+  nousresearch/hermes-agent\n+```\n+\n+## Upgrading\n+\n+Pull the latest image and recreate the container. Your data directory is untouched.\n+\n+```sh\n+docker pull nousresearch/hermes-agent:latest\n+docker rm -f hermes\n+docker run -d \\\n+  --name hermes \\\n+  --restart unless-stopped \\\n+  -v ~/.hermes:/opt/data \\\n+  nousresearch/hermes-agent\n+```"]},{"file":"website/sidebars.ts","hunks":["@@ -37,6 +37,7 @@ const sidebars: SidebarsConfig = {\n         'user-guide/configuration',\n         'user-guide/sessions',\n         'user-guide/security',\n+        'user-guide/docker',\n         {\n           type: 'category',\n           label: 'Messaging Gateway',\n"]}]}],"trust":{"default_tier":"verified","includes_suggested":false}}