From 4e566b24081c114c9be79418ec51121f43eb0d31 Mon Sep 17 00:00:00 2001 From: Hermes Date: Wed, 20 May 2026 13:14:10 -0400 Subject: [PATCH] fix: resolve Docker build errors and add Traefik routing for Hermes web UI - Replace rsync with cp -a (rsync unavailable in latest upstream base image) - Remove npm run build step (fork's package.json has no build script) - Remove himalaya-ro.sh from build context (deployed via install.sh) - Add hermes to ai_net network for Traefik access - Add Traefik labels routing hermes.lazyworkhorse.net to dashboard port 9119 --- ai/compose.yml | 18 ++++++++++ ai/hermes/Dockerfile | 14 ++------ ai/hermes/himalaya-ro.sh | 73 ---------------------------------------- 3 files changed, 20 insertions(+), 85 deletions(-) delete mode 100644 ai/hermes/himalaya-ro.sh diff --git a/ai/compose.yml b/ai/compose.yml index 1db7831..17d6170 100644 --- a/ai/compose.yml +++ b/ai/compose.yml @@ -66,6 +66,24 @@ services: - "26" networks: - ai_backend + - ai_net + labels: + - "traefik.enable=true" + - "traefik.docker.network=ai_net" + + # Router for HTTP + redirection to HTTPS + - "traefik.http.routers.hermes-web-http.rule=Host(`hermes.lazyworkhorse.net`)" + - "traefik.http.routers.hermes-web-http.entrypoints=web" + - "traefik.http.routers.hermes-web-http.middlewares=redirect-to-https" + + # Router for HTTPS with TLS + - "traefik.http.routers.hermes-web-https.rule=Host(`hermes.lazyworkhorse.net`)" + - "traefik.http.routers.hermes-web-https.entrypoints=websecure" + - "traefik.http.routers.hermes-web-https.tls=true" + - "traefik.http.routers.hermes-web-https.tls.certresolver=njalla" + + # Service Loadbalancer (dashboard port 9119) + - "traefik.http.services.hermes-web.loadbalancer.server.port=9119" syncthing: image: syncthing/syncthing:latest diff --git a/ai/hermes/Dockerfile b/ai/hermes/Dockerfile index a6edcfc..1b775e7 100644 --- a/ai/hermes/Dockerfile +++ b/ai/hermes/Dockerfile @@ -20,16 +20,10 @@ RUN --mount=type=ssh \ GIT_SSH_COMMAND='ssh -p 2222 -o StrictHostKeyChecking=no' \ git clone --depth 1 --branch main \ git@code.lazyworkhorse.net:gortium/hermes-agent.git fork && \ - rsync -a --delete fork/ /opt/hermes/ \ - --exclude node_modules \ - --exclude .venv \ - --exclude .git && \ + rm -rf fork/node_modules fork/.venv fork/.git && \ + cp -a fork/. /opt/hermes/ && \ rm -rf /tmp/fork /root/.ssh/ -# ---------- Rebuild web UI ---------- -# Source files changed; node_modules (from base image) reused. -RUN cd /opt/hermes && npm run build - # ---------- Reinstall Python package (editable) ---------- # Picks up source changes from our fork. RUN . /opt/hermes/.venv/bin/activate && \ @@ -75,10 +69,6 @@ os.remove(tgz) print('himalaya v1.2.0 installed') PYEOF -# ---------- Install himalaya-ro wrapper ---------- -COPY --chmod=0755 himalaya-ro.sh /usr/local/bin/himalaya-ro - - # ---------- Runtime ---------- USER hermes ENV HERMES_HOME=/opt/data diff --git a/ai/hermes/himalaya-ro.sh b/ai/hermes/himalaya-ro.sh deleted file mode 100644 index 212f1ae..0000000 --- a/ai/hermes/himalaya-ro.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash -# ───────────────────────────────────────────────────────────── -# himalaya-ro — Read-only wrapper for himalaya -# -# Blocks destructive commands and logs audit trail. -# Pass-through for read-only commands (list, read, search). -# -# Usage: himalaya-ro [options] [args...] -# -# Install: place in PATH before the real himalaya, or use -# `ln -sf himalaya-ro /usr/local/bin/himalaya` -# ───────────────────────────────────────────────────────────── -set -o pipefail - -# ── Configuration ─────────────────────────────────────────── -HIMALAYA_BIN="${HIMALAYA_BIN:-/usr/local/bin/himalaya}" -AUDIT_LOG="${HIMALAYA_AUDIT_LOG:-/var/log/himalaya-audit.log}" - -# ── Destructive commands we block ────────────────────────── -BLOCKED_CMDS=( - "message move" - "message delete" - "message copy" - "flag add" - "flag remove" - "folder create" - "folder delete" - "folder rename" - "template send" - "account configure" - "account delete" -) - -# ── Determine the subcommand being invoked ───────────────── -# Strip leading options (--account, --output, etc.) to find the verb -ARGS=() -SKIP_NEXT=false -for arg in "$@"; do - if $SKIP_NEXT; then - SKIP_NEXT=false - continue - fi - if [[ "$arg" == --* ]]; then - case "$arg" in - --account|--output|--page|--page-size|--folder|--color|--format) - SKIP_NEXT=true ;; - esac - continue - fi - ARGS+=("$arg") -done - -# Build subcommand string and check against blocklist -CMD_STR="" -for ((i=0; i<${#ARGS[@]}; i++)); do - if [ -z "$CMD_STR" ]; then - CMD_STR="${ARGS[$i]}" - else - CMD_STR="$CMD_STR ${ARGS[$i]}" - fi - for blocked in "${BLOCKED_CMDS[@]}"; do - if [[ "$CMD_STR" == "$blocked" ]]; then - TS=$(date '+%Y-%m-%d %H:%M:%S') - echo "[AUDIT] $TS BLOCKED: himalaya $*" >> "$AUDIT_LOG" - echo "ERROR: Command 'himalaya $CMD_STR ...' is blocked by read-only policy." >&2 - echo " Audit log: $AUDIT_LOG" >&2 - exit 100 - fi - done -done - -# ── Allow pass-through ───────────────────────────────────── -exec "$HIMALAYA_BIN" "$@"