From 0086e28ed878df9defd8ff0a98752955b1ac2967 Mon Sep 17 00:00:00 2001 From: okxlin <61420215+okxlin@users.noreply.github.com> Date: Sat, 17 Oct 2026 07:48:50 +0800 Subject: [PATCH] fix(hermes-dashboard): preserve 2026.9.21 upgrade source --- apps/hermes-dashboard/2026.9.24/.env.sample | 10 ++ apps/hermes-dashboard/2026.9.24/data.yml | 169 ++++++++++++++++++ .../2026.9.24/docker-compose.yml | 30 ++++ .../2026.9.24/scripts/init.sh | 77 ++++++++ .../2026.9.24/scripts/uninstall.sh | 2 + .../2026.9.24/scripts/upgrade.sh | 77 ++++++++ 6 files changed, 365 insertions(+) create mode 100755 apps/hermes-dashboard/2026.9.24/.env.sample create mode 100755 apps/hermes-dashboard/2026.9.24/data.yml create mode 100755 apps/hermes-dashboard/2026.9.24/docker-compose.yml create mode 100755 apps/hermes-dashboard/2026.9.24/scripts/init.sh create mode 100755 apps/hermes-dashboard/2026.9.24/scripts/uninstall.sh create mode 100755 apps/hermes-dashboard/2026.9.24/scripts/upgrade.sh diff --git a/apps/hermes-dashboard/2026.9.24/.env.sample b/apps/hermes-dashboard/2026.9.24/.env.sample new file mode 100755 index 000000000..403e8cea0 --- /dev/null +++ b/apps/hermes-dashboard/2026.9.24/.env.sample @@ -0,0 +1,10 @@ +CONTAINER_NAME=hermes-dashboard +TZ=Asia/Shanghai +APP_DATA_DIR=/opt/1panel/apps/local/hermes-agent/hermes-agent/data +HERMES_UID=10000 +HERMES_GID=10000 +PANEL_APP_PORT_HTTP=9119 +GATEWAY_HEALTH_URL=http://172.18.0.240:8642 +DASHBOARD_USERNAME=admin +DASHBOARD_PASSWORD=change_me_with_a_strong_password +DASHBOARD_SESSION_SECRET=change_me_with_a_random_session_secret diff --git a/apps/hermes-dashboard/2026.9.24/data.yml b/apps/hermes-dashboard/2026.9.24/data.yml new file mode 100755 index 000000000..9c2f60a5a --- /dev/null +++ b/apps/hermes-dashboard/2026.9.24/data.yml @@ -0,0 +1,169 @@ +additionalProperties: + formFields: + - default: "Hermes Dashboard 是附属应用。请先部署 Hermes gateway,并把 APP_DATA_DIR 指向 Hermes Agent 的同一份数据目录,再把 GATEWAY_HEALTH_URL 填成它的完整地址。公开绑定现在强制启用认证,`--insecure` 已不能绕过认证;请设置 Dashboard 用户名、强密码和会话签名密钥。旧版本升级时,脚本只会为缺失或空白的认证项生成随机值,不会覆盖已有配置;升级完成后请在应用参数中设置自己知道的密码。" + disabled: true + envKey: TIPS + labelEn: Tips + labelZh: 提示 + label: + en: Tips + zh: 提示 + zh-Hant: 提示 + ja: ヒント + ko: 팁 + ru: Подсказка + ms: Petua + pt-br: Dicas + edit: true + required: true + type: text + - default: Asia/Shanghai + envKey: TZ + labelEn: Timezone + labelZh: 时区 + label: + en: Timezone + zh: 时区 + zh-Hant: 時區 + ja: タイムゾーン + ko: 시간대 + ru: Часовой пояс + ms: Zon waktu + pt-br: Fuso horário + edit: true + required: true + type: text + - default: /opt/1panel/apps/local/hermes-agent/hermes-agent/data + envKey: APP_DATA_DIR + labelEn: Data Directory + labelZh: 数据目录 + label: + en: Data Directory + zh: 数据目录 + zh-Hant: 資料目錄 + ja: データディレクトリ + ko: 데이터 디렉터리 + ru: Каталог данных + ms: Direktori data + pt-br: Diretório de dados + edit: true + required: true + type: text + - default: 10000 + envKey: HERMES_UID + labelEn: Hermes Runtime UID + labelZh: Hermes 运行用户 UID + label: + en: Hermes Runtime UID + zh: Hermes 运行用户 UID + zh-Hant: Hermes 執行使用者 UID + ja: Hermes 実行ユーザー UID + ko: Hermes 실행 사용자 UID + ru: UID пользователя Hermes + ms: UID pengguna runtime Hermes + pt-br: UID do usuário de execução do Hermes + edit: true + required: true + type: number + - default: 10000 + envKey: HERMES_GID + labelEn: Hermes Runtime GID + labelZh: Hermes 运行用户 GID + label: + en: Hermes Runtime GID + zh: Hermes 运行用户 GID + zh-Hant: Hermes 執行使用者 GID + ja: Hermes 実行ユーザー GID + ko: Hermes 실행 사용자 GID + ru: GID пользователя Hermes + ms: GID pengguna runtime Hermes + pt-br: GID do usuário de execução do Hermes + edit: true + required: true + type: number + - default: 9119 + envKey: PANEL_APP_PORT_HTTP + labelEn: Dashboard Port + labelZh: Dashboard 端口 + label: + en: Dashboard Port + zh: Dashboard 端口 + zh-Hant: Dashboard 連接埠 + ja: Dashboard ポート + ko: 대시보드 포트 + ru: Порт dashboard + ms: Port dashboard + pt-br: Porta do dashboard + edit: true + required: true + rule: paramPort + type: number + - default: http://172.18.0.240:8642 + envKey: GATEWAY_HEALTH_URL + labelEn: Gateway Health URL + labelZh: 网关健康检查 URL + label: + en: Gateway Health URL + zh: 网关健康检查 URL + zh-Hant: 閘道健康檢查 URL + ja: Gateway ヘルス URL + ko: 게이트웨이 헬스 URL + ru: URL проверки шлюза + ms: URL kesihatan gateway + pt-br: URL de verificação do gateway + edit: true + required: true + rule: paramExtUrl + type: text + - default: admin + envKey: DASHBOARD_USERNAME + labelEn: Dashboard Username + labelZh: Dashboard 用户名 + label: + en: Dashboard Username + zh: Dashboard 用户名 + zh-Hant: Dashboard 使用者名稱 + ja: Dashboard ユーザー名 + ko: Dashboard 사용자 이름 + ru: Имя пользователя dashboard + ms: Nama pengguna dashboard + pt-br: Usuário do dashboard + edit: true + required: true + type: text + - default: "" + envKey: DASHBOARD_PASSWORD + labelEn: Dashboard Password + labelZh: Dashboard 密码 + label: + en: Dashboard Password + zh: Dashboard 密码 + zh-Hant: Dashboard 密碼 + ja: Dashboard パスワード + ko: Dashboard 비밀번호 + ru: Пароль dashboard + ms: Kata laluan dashboard + pt-br: Senha do dashboard + edit: true + random: true + required: true + rule: paramComplexity + type: password + - default: "" + envKey: DASHBOARD_SESSION_SECRET + labelEn: Dashboard Session Secret + labelZh: Dashboard 会话签名密钥 + label: + en: Dashboard Session Secret + zh: Dashboard 会话签名密钥 + zh-Hant: Dashboard 工作階段簽章密鑰 + ja: Dashboard セッション署名シークレット + ko: Dashboard 세션 서명 비밀값 + ru: Секрет подписи сессии dashboard + ms: Rahsia tandatangan sesi dashboard + pt-br: Segredo de assinatura da sessão do dashboard + edit: true + random: true + required: true + rule: paramComplexity + type: password diff --git a/apps/hermes-dashboard/2026.9.24/docker-compose.yml b/apps/hermes-dashboard/2026.9.24/docker-compose.yml new file mode 100755 index 000000000..285822422 --- /dev/null +++ b/apps/hermes-dashboard/2026.9.24/docker-compose.yml @@ -0,0 +1,30 @@ +services: + hermes-dashboard: + image: "nousresearch/hermes-agent:v2026.9.24" + container_name: ${CONTAINER_NAME} + command: + - dashboard + - --host + - 0.0.0.0 + - --no-open + environment: + - TZ=${TZ} + - HERMES_UID=${HERMES_UID:-10000} + - HERMES_GID=${HERMES_GID:-10000} + - GATEWAY_HEALTH_URL=${GATEWAY_HEALTH_URL} + - HERMES_DASHBOARD_BASIC_AUTH_USERNAME=${DASHBOARD_USERNAME} + - HERMES_DASHBOARD_BASIC_AUTH_PASSWORD=${DASHBOARD_PASSWORD} + - HERMES_DASHBOARD_BASIC_AUTH_SECRET=${DASHBOARD_SESSION_SECRET} + ports: + - "${PANEL_APP_PORT_HTTP}:9119" + volumes: + - "${APP_DATA_DIR}:/opt/data" + restart: unless-stopped + networks: + - 1panel-network + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/apps/hermes-dashboard/2026.9.24/scripts/init.sh b/apps/hermes-dashboard/2026.9.24/scripts/init.sh new file mode 100755 index 000000000..c46d420b4 --- /dev/null +++ b/apps/hermes-dashboard/2026.9.24/scripts/init.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +ENV_FILE="$ROOT_DIR/.env" +APP_DATA_DIR_RAW="${APP_DATA_DIR:-./data}" +DEFAULT_UID="10000" +DEFAULT_GID="10000" +TARGET_UID="${HERMES_UID:-$DEFAULT_UID}" +TARGET_GID="${HERMES_GID:-$DEFAULT_GID}" + +if [[ "$APP_DATA_DIR_RAW" = /* ]]; then + APP_DATA_DIR_ABS="$APP_DATA_DIR_RAW" +else + APP_DATA_DIR_ABS="$ROOT_DIR/${APP_DATA_DIR_RAW#./}" +fi + +mkdir -p "$APP_DATA_DIR_ABS" + +upsert_env_if_missing() { + local key="$1" + local value="$2" + + if [[ ! -f "$ENV_FILE" ]]; then + return 0 + fi + + if ! grep -q "^${key}=" "$ENV_FILE" 2>/dev/null; then + printf '\n%s=%s\n' "$key" "$value" >> "$ENV_FILE" + fi +} + +generate_random_value() { + local length="$1" + local value="" + + while [[ ${#value} -lt $length ]]; do + value+="$(LC_ALL=C tr -dc 'A-Za-z0-9' /dev/null; then + printf '\n%s=%s\n' "$key" "$value" >> "$ENV_FILE" + elif grep -Eq "^${key}=([[:space:]]*|\"\"|'')$" "$ENV_FILE"; then + sed -i "s|^${key}=.*|${key}=${value}|" "$ENV_FILE" + fi +} + +if [[ -f "$ENV_FILE" ]]; then + EXISTING_UID=$(grep '^HERMES_UID=' "$ENV_FILE" 2>/dev/null | tail -n 1 | cut -d '=' -f 2- || true) + EXISTING_GID=$(grep '^HERMES_GID=' "$ENV_FILE" 2>/dev/null | tail -n 1 | cut -d '=' -f 2- || true) + [[ -n "$EXISTING_UID" ]] && TARGET_UID="$EXISTING_UID" + [[ -n "$EXISTING_GID" ]] && TARGET_GID="$EXISTING_GID" +fi + +upsert_env_if_missing "HERMES_UID" "$TARGET_UID" +upsert_env_if_missing "HERMES_GID" "$TARGET_GID" +ensure_env_value "DASHBOARD_USERNAME" "admin" +ensure_env_value "DASHBOARD_PASSWORD" "$(generate_random_value 32)" +ensure_env_value "DASHBOARD_SESSION_SECRET" "$(generate_random_value 48)" + +CURRENT_UID=$(stat -c '%u' "$APP_DATA_DIR_ABS" 2>/dev/null || echo '') +CURRENT_GID=$(stat -c '%g' "$APP_DATA_DIR_ABS" 2>/dev/null || echo '') + +if [[ "$CURRENT_UID" != "$TARGET_UID" || "$CURRENT_GID" != "$TARGET_GID" ]]; then + chown -R "$TARGET_UID:$TARGET_GID" "$APP_DATA_DIR_ABS" 2>/dev/null || true +fi diff --git a/apps/hermes-dashboard/2026.9.24/scripts/uninstall.sh b/apps/hermes-dashboard/2026.9.24/scripts/uninstall.sh new file mode 100755 index 000000000..ab8a8d674 --- /dev/null +++ b/apps/hermes-dashboard/2026.9.24/scripts/uninstall.sh @@ -0,0 +1,2 @@ +#!/bin/bash +docker-compose down --volumes diff --git a/apps/hermes-dashboard/2026.9.24/scripts/upgrade.sh b/apps/hermes-dashboard/2026.9.24/scripts/upgrade.sh new file mode 100755 index 000000000..c46d420b4 --- /dev/null +++ b/apps/hermes-dashboard/2026.9.24/scripts/upgrade.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +ENV_FILE="$ROOT_DIR/.env" +APP_DATA_DIR_RAW="${APP_DATA_DIR:-./data}" +DEFAULT_UID="10000" +DEFAULT_GID="10000" +TARGET_UID="${HERMES_UID:-$DEFAULT_UID}" +TARGET_GID="${HERMES_GID:-$DEFAULT_GID}" + +if [[ "$APP_DATA_DIR_RAW" = /* ]]; then + APP_DATA_DIR_ABS="$APP_DATA_DIR_RAW" +else + APP_DATA_DIR_ABS="$ROOT_DIR/${APP_DATA_DIR_RAW#./}" +fi + +mkdir -p "$APP_DATA_DIR_ABS" + +upsert_env_if_missing() { + local key="$1" + local value="$2" + + if [[ ! -f "$ENV_FILE" ]]; then + return 0 + fi + + if ! grep -q "^${key}=" "$ENV_FILE" 2>/dev/null; then + printf '\n%s=%s\n' "$key" "$value" >> "$ENV_FILE" + fi +} + +generate_random_value() { + local length="$1" + local value="" + + while [[ ${#value} -lt $length ]]; do + value+="$(LC_ALL=C tr -dc 'A-Za-z0-9' /dev/null; then + printf '\n%s=%s\n' "$key" "$value" >> "$ENV_FILE" + elif grep -Eq "^${key}=([[:space:]]*|\"\"|'')$" "$ENV_FILE"; then + sed -i "s|^${key}=.*|${key}=${value}|" "$ENV_FILE" + fi +} + +if [[ -f "$ENV_FILE" ]]; then + EXISTING_UID=$(grep '^HERMES_UID=' "$ENV_FILE" 2>/dev/null | tail -n 1 | cut -d '=' -f 2- || true) + EXISTING_GID=$(grep '^HERMES_GID=' "$ENV_FILE" 2>/dev/null | tail -n 1 | cut -d '=' -f 2- || true) + [[ -n "$EXISTING_UID" ]] && TARGET_UID="$EXISTING_UID" + [[ -n "$EXISTING_GID" ]] && TARGET_GID="$EXISTING_GID" +fi + +upsert_env_if_missing "HERMES_UID" "$TARGET_UID" +upsert_env_if_missing "HERMES_GID" "$TARGET_GID" +ensure_env_value "DASHBOARD_USERNAME" "admin" +ensure_env_value "DASHBOARD_PASSWORD" "$(generate_random_value 32)" +ensure_env_value "DASHBOARD_SESSION_SECRET" "$(generate_random_value 48)" + +CURRENT_UID=$(stat -c '%u' "$APP_DATA_DIR_ABS" 2>/dev/null || echo '') +CURRENT_GID=$(stat -c '%g' "$APP_DATA_DIR_ABS" 2>/dev/null || echo '') + +if [[ "$CURRENT_UID" != "$TARGET_UID" || "$CURRENT_GID" != "$TARGET_GID" ]]; then + chown -R "$TARGET_UID:$TARGET_GID" "$APP_DATA_DIR_ABS" 2>/dev/null || true +fi