Spaces:
Running
Running
feat: update Dockerfile and start.sh to use python3 and enhance startup banner
Browse files- Dockerfile +1 -0
- start.sh +46 -15
Dockerfile
CHANGED
|
@@ -9,6 +9,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
| 9 |
ca-certificates \
|
| 10 |
curl \
|
| 11 |
jq \
|
|
|
|
| 12 |
&& rm -rf /var/lib/apt/lists/* \
|
| 13 |
&& uv pip install --python /opt/hermes/.venv/bin/python --no-cache-dir huggingface_hub
|
| 14 |
|
|
|
|
| 9 |
ca-certificates \
|
| 10 |
curl \
|
| 11 |
jq \
|
| 12 |
+
python3 \
|
| 13 |
&& rm -rf /var/lib/apt/lists/* \
|
| 14 |
&& uv pip install --python /opt/hermes/.venv/bin/python --no-cache-dir huggingface_hub
|
| 15 |
|
start.sh
CHANGED
|
@@ -3,6 +3,11 @@ set -euo pipefail
|
|
| 3 |
|
| 4 |
umask 0077
|
| 5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
APP_DIR="${HUGGINGMESS_APP_DIR:-/opt/huggingmess}"
|
| 7 |
HERMES_HOME="${HERMES_HOME:-/opt/data}"
|
| 8 |
PUBLIC_PORT="${PORT:-7861}"
|
|
@@ -20,11 +25,17 @@ export API_SERVER_PORT="$GATEWAY_API_PORT"
|
|
| 20 |
export GATEWAY_HEALTH_URL="${GATEWAY_HEALTH_URL:-http://127.0.0.1:${GATEWAY_API_PORT}}"
|
| 21 |
export TELEGRAM_WEBHOOK_PORT
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
if [ -z "${API_SERVER_KEY:-}" ]; then
|
| 24 |
if [ -n "${GATEWAY_TOKEN:-}" ]; then
|
| 25 |
export API_SERVER_KEY="$GATEWAY_TOKEN"
|
| 26 |
else
|
| 27 |
-
API_SERVER_KEY="$(
|
| 28 |
import secrets
|
| 29 |
print(secrets.token_urlsafe(32))
|
| 30 |
PY
|
|
@@ -34,17 +45,13 @@ PY
|
|
| 34 |
fi
|
| 35 |
fi
|
| 36 |
|
| 37 |
-
|
| 38 |
-
echo " =========================================="
|
| 39 |
-
echo " HuggingMess Hermes Gateway"
|
| 40 |
-
echo " =========================================="
|
| 41 |
-
echo ""
|
| 42 |
-
|
| 43 |
mkdir -p "$HERMES_HOME"/{cron,sessions,logs,hooks,memories,skills,skins,plans,workspace,home}
|
| 44 |
|
|
|
|
| 45 |
if [ -n "${HF_TOKEN:-}" ]; then
|
| 46 |
echo "Restoring Hermes state from HF Dataset..."
|
| 47 |
-
|
| 48 |
else
|
| 49 |
echo "HF_TOKEN not set - dataset persistence is disabled."
|
| 50 |
fi
|
|
@@ -54,7 +61,7 @@ export CLOUDFLARE_WORKERS_TOKEN
|
|
| 54 |
if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ] || [ -n "${CLOUDFLARE_PROXY_URL:-}" ]; then
|
| 55 |
export CLOUDFLARE_PROXY_DEBUG="${CLOUDFLARE_PROXY_DEBUG:-false}"
|
| 56 |
echo "Preparing Cloudflare Telegram proxy..."
|
| 57 |
-
|
| 58 |
if [ -f "$CF_PROXY_ENV_FILE" ]; then
|
| 59 |
. "$CF_PROXY_ENV_FILE"
|
| 60 |
fi
|
|
@@ -62,7 +69,7 @@ fi
|
|
| 62 |
|
| 63 |
if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ]; then
|
| 64 |
echo "Preparing Cloudflare Keepalive worker..."
|
| 65 |
-
|
| 66 |
fi
|
| 67 |
|
| 68 |
if [ -n "${TELEGRAM_USER_IDS:-}" ] && [ -z "${TELEGRAM_ALLOWED_USERS:-}" ]; then
|
|
@@ -83,7 +90,7 @@ if [ -n "${TELEGRAM_WEBHOOK_URL:-}" ] && [ -z "${TELEGRAM_WEBHOOK_SECRET:-}" ];
|
|
| 83 |
export TELEGRAM_WEBHOOK_SECRET
|
| 84 |
TELEGRAM_WEBHOOK_SECRET="$(cat "$SECRET_FILE")"
|
| 85 |
else
|
| 86 |
-
TELEGRAM_WEBHOOK_SECRET="$(
|
| 87 |
import secrets
|
| 88 |
print(secrets.token_hex(32))
|
| 89 |
PY
|
|
@@ -183,7 +190,8 @@ if [ -n "${CLOUDFLARE_PROXY_URL:-}" ] && [ -z "$TELEGRAM_BASE_URL" ]; then
|
|
| 183 |
export TELEGRAM_BASE_FILE_URL="${CLOUDFLARE_PROXY_URL}/file/bot"
|
| 184 |
fi
|
| 185 |
|
| 186 |
-
|
|
|
|
| 187 |
import os
|
| 188 |
from pathlib import Path
|
| 189 |
|
|
@@ -243,22 +251,44 @@ path.write_text(yaml.safe_dump(config, sort_keys=False), encoding="utf-8")
|
|
| 243 |
path.chmod(0o600)
|
| 244 |
PY
|
| 245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
|
|
|
|
| 247 |
graceful_shutdown() {
|
| 248 |
echo "Shutting down HuggingMess..."
|
| 249 |
if [ -n "${HF_TOKEN:-}" ]; then
|
| 250 |
-
|
| 251 |
fi
|
| 252 |
kill $(jobs -p) 2>/dev/null || true
|
| 253 |
exit 0
|
| 254 |
}
|
| 255 |
trap graceful_shutdown SIGTERM SIGINT
|
| 256 |
|
|
|
|
| 257 |
node "$APP_DIR/health-server.js" &
|
| 258 |
HEALTH_PID=$!
|
| 259 |
|
| 260 |
if [ -n "${WEBHOOK_URL:-}" ]; then
|
| 261 |
-
|
| 262 |
import json, os, urllib.request
|
| 263 |
body = json.dumps({
|
| 264 |
"event": "restart",
|
|
@@ -275,6 +305,7 @@ echo "Launching Hermes dashboard on 127.0.0.1:${DASHBOARD_PORT}..."
|
|
| 275 |
(hermes dashboard --host 127.0.0.1 --insecure 2>&1 | tee -a "$HERMES_HOME/logs/dashboard.log") &
|
| 276 |
DASHBOARD_PID=$!
|
| 277 |
|
|
|
|
| 278 |
echo "Launching Hermes gateway..."
|
| 279 |
(hermes gateway run 2>&1 | tee -a "$HERMES_HOME/logs/gateway.log") &
|
| 280 |
GATEWAY_PID=$!
|
|
@@ -301,7 +332,7 @@ if [ "$ready" != "true" ]; then
|
|
| 301 |
fi
|
| 302 |
|
| 303 |
if [ -n "${HF_TOKEN:-}" ]; then
|
| 304 |
-
|
| 305 |
fi
|
| 306 |
|
| 307 |
wait "$GATEWAY_PID"
|
|
|
|
| 3 |
|
| 4 |
umask 0077
|
| 5 |
|
| 6 |
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 7 |
+
# HuggingMess β Hermes Gateway for HF Spaces
|
| 8 |
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 9 |
+
|
| 10 |
+
# ββ Startup Banner ββ
|
| 11 |
APP_DIR="${HUGGINGMESS_APP_DIR:-/opt/huggingmess}"
|
| 12 |
HERMES_HOME="${HERMES_HOME:-/opt/data}"
|
| 13 |
PUBLIC_PORT="${PORT:-7861}"
|
|
|
|
| 25 |
export GATEWAY_HEALTH_URL="${GATEWAY_HEALTH_URL:-http://127.0.0.1:${GATEWAY_API_PORT}}"
|
| 26 |
export TELEGRAM_WEBHOOK_PORT
|
| 27 |
|
| 28 |
+
echo ""
|
| 29 |
+
echo " ββββββββββββββββββββββββββββββββββββββββββββ"
|
| 30 |
+
echo " β π¬ HuggingMess Hermes Gateway β"
|
| 31 |
+
echo " ββββββββββββββββββββββββββββββββββββββββββββ"
|
| 32 |
+
echo ""
|
| 33 |
+
|
| 34 |
if [ -z "${API_SERVER_KEY:-}" ]; then
|
| 35 |
if [ -n "${GATEWAY_TOKEN:-}" ]; then
|
| 36 |
export API_SERVER_KEY="$GATEWAY_TOKEN"
|
| 37 |
else
|
| 38 |
+
API_SERVER_KEY="$(python3 - <<'PY'
|
| 39 |
import secrets
|
| 40 |
print(secrets.token_urlsafe(32))
|
| 41 |
PY
|
|
|
|
| 45 |
fi
|
| 46 |
fi
|
| 47 |
|
| 48 |
+
# ββ Setup directories ββ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
mkdir -p "$HERMES_HOME"/{cron,sessions,logs,hooks,memories,skills,skins,plans,workspace,home}
|
| 50 |
|
| 51 |
+
# ββ Restore workspace/state from HF Dataset ββ
|
| 52 |
if [ -n "${HF_TOKEN:-}" ]; then
|
| 53 |
echo "Restoring Hermes state from HF Dataset..."
|
| 54 |
+
python3 "$APP_DIR/hermes-sync.py" restore || true
|
| 55 |
else
|
| 56 |
echo "HF_TOKEN not set - dataset persistence is disabled."
|
| 57 |
fi
|
|
|
|
| 61 |
if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ] || [ -n "${CLOUDFLARE_PROXY_URL:-}" ]; then
|
| 62 |
export CLOUDFLARE_PROXY_DEBUG="${CLOUDFLARE_PROXY_DEBUG:-false}"
|
| 63 |
echo "Preparing Cloudflare Telegram proxy..."
|
| 64 |
+
python3 "$APP_DIR/cloudflare-proxy-setup.py" || true
|
| 65 |
if [ -f "$CF_PROXY_ENV_FILE" ]; then
|
| 66 |
. "$CF_PROXY_ENV_FILE"
|
| 67 |
fi
|
|
|
|
| 69 |
|
| 70 |
if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ]; then
|
| 71 |
echo "Preparing Cloudflare Keepalive worker..."
|
| 72 |
+
python3 "$APP_DIR/cloudflare-keepalive-setup.py" || true
|
| 73 |
fi
|
| 74 |
|
| 75 |
if [ -n "${TELEGRAM_USER_IDS:-}" ] && [ -z "${TELEGRAM_ALLOWED_USERS:-}" ]; then
|
|
|
|
| 90 |
export TELEGRAM_WEBHOOK_SECRET
|
| 91 |
TELEGRAM_WEBHOOK_SECRET="$(cat "$SECRET_FILE")"
|
| 92 |
else
|
| 93 |
+
TELEGRAM_WEBHOOK_SECRET="$(python3 - <<'PY'
|
| 94 |
import secrets
|
| 95 |
print(secrets.token_hex(32))
|
| 96 |
PY
|
|
|
|
| 190 |
export TELEGRAM_BASE_FILE_URL="${CLOUDFLARE_PROXY_URL}/file/bot"
|
| 191 |
fi
|
| 192 |
|
| 193 |
+
# ββ Build config ββ
|
| 194 |
+
python3 - <<'PY'
|
| 195 |
import os
|
| 196 |
from pathlib import Path
|
| 197 |
|
|
|
|
| 251 |
path.chmod(0o600)
|
| 252 |
PY
|
| 253 |
|
| 254 |
+
# ββ Startup Summary ββ
|
| 255 |
+
echo ""
|
| 256 |
+
echo "Model : ${MODEL_FOR_CONFIG:-unset}"
|
| 257 |
+
echo "Provider : ${PROVIDER_FOR_CONFIG:-unset}"
|
| 258 |
+
if [ -n "${TELEGRAM_BOT_TOKEN:-}" ]; then
|
| 259 |
+
echo "Telegram : enabled"
|
| 260 |
+
else
|
| 261 |
+
echo "Telegram : not configured"
|
| 262 |
+
fi
|
| 263 |
+
if [ -n "${HF_TOKEN:-}" ]; then
|
| 264 |
+
echo "Backup : ${BACKUP_DATASET} (every ${SYNC_INTERVAL:-180}s)"
|
| 265 |
+
else
|
| 266 |
+
echo "Backup : disabled"
|
| 267 |
+
fi
|
| 268 |
+
if [ -n "${CLOUDFLARE_PROXY_URL:-}" ]; then
|
| 269 |
+
echo "Proxy : ${CLOUDFLARE_PROXY_URL}"
|
| 270 |
+
fi
|
| 271 |
+
echo "Dashboard : http://127.0.0.1:${DASHBOARD_PORT}"
|
| 272 |
+
echo "Gateway : http://127.0.0.1:${GATEWAY_API_PORT}"
|
| 273 |
+
echo ""
|
| 274 |
|
| 275 |
+
# ββ Trap SIGTERM for graceful shutdown ββ
|
| 276 |
graceful_shutdown() {
|
| 277 |
echo "Shutting down HuggingMess..."
|
| 278 |
if [ -n "${HF_TOKEN:-}" ]; then
|
| 279 |
+
python3 "$APP_DIR/hermes-sync.py" sync-once || echo "Warning: shutdown sync failed."
|
| 280 |
fi
|
| 281 |
kill $(jobs -p) 2>/dev/null || true
|
| 282 |
exit 0
|
| 283 |
}
|
| 284 |
trap graceful_shutdown SIGTERM SIGINT
|
| 285 |
|
| 286 |
+
# ββ Start background services ββ
|
| 287 |
node "$APP_DIR/health-server.js" &
|
| 288 |
HEALTH_PID=$!
|
| 289 |
|
| 290 |
if [ -n "${WEBHOOK_URL:-}" ]; then
|
| 291 |
+
python3 - <<'PY' >/dev/null 2>&1 &
|
| 292 |
import json, os, urllib.request
|
| 293 |
body = json.dumps({
|
| 294 |
"event": "restart",
|
|
|
|
| 305 |
(hermes dashboard --host 127.0.0.1 --insecure 2>&1 | tee -a "$HERMES_HOME/logs/dashboard.log") &
|
| 306 |
DASHBOARD_PID=$!
|
| 307 |
|
| 308 |
+
# ββ Launch gateway ββ
|
| 309 |
echo "Launching Hermes gateway..."
|
| 310 |
(hermes gateway run 2>&1 | tee -a "$HERMES_HOME/logs/gateway.log") &
|
| 311 |
GATEWAY_PID=$!
|
|
|
|
| 332 |
fi
|
| 333 |
|
| 334 |
if [ -n "${HF_TOKEN:-}" ]; then
|
| 335 |
+
python3 -u "$APP_DIR/hermes-sync.py" loop &
|
| 336 |
fi
|
| 337 |
|
| 338 |
wait "$GATEWAY_PID"
|