From c3e9b7edbc187d3f0cfba7145424b7d4726752ba Mon Sep 17 00:00:00 2001 From: kris Date: Mon, 6 Apr 2026 10:34:01 +0800 Subject: [PATCH] feat: migrate public n8n and huobao to server --- CHANGELOG.md | 7 +++ deploy/storyforge-server-huobao.compose.yaml | 25 +++++++++++ deploy/storyforge-server-n8n.compose.yaml | 27 ++++++++++++ scripts/deploy_server_storyforge_huobao.sh | 45 ++++++++++++++++++++ scripts/deploy_server_storyforge_n8n.sh | 34 +++++++++++++++ 5 files changed, 138 insertions(+) create mode 100644 deploy/storyforge-server-huobao.compose.yaml create mode 100644 deploy/storyforge-server-n8n.compose.yaml create mode 100755 scripts/deploy_server_storyforge_huobao.sh create mode 100755 scripts/deploy_server_storyforge_n8n.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c19512..3097f5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ ## 2026-04-06 +### 公网 n8n 与火爆视频迁到服务器本机 + +- 公网 `n8n` 不再依赖旧的 SSH 反向隧道,已经迁到服务器本机 Docker,健康检查地址切到 `127.0.0.1:25670/healthz`。 +- 公网 `huobao` 也已经从外部依赖迁到服务器本机 Docker,健康检查地址切到 `127.0.0.1:25678/health`。 +- 公网 `collector` 现已统一使用服务器本机的 `n8n + huobao + cutvideo + live_recorder`,同时继续保持 `local_model` 禁用、`ASR` 走 Windows 桥接。 +- 这让外网主链不再依赖你当前这台 Mac 或旧的 `192.168.31.139` 服务状态,公网 `integrations/health` 里 `n8n / huobao / asr / cutvideo / live_recorder` 现在都恢复为在线。 + ### 自动连接首屏再提速一层 - 自动连接成功后,`/v2/me` 和 `/v2/me/dashboard` 现在改成并行请求,不再串行等待。 diff --git a/deploy/storyforge-server-huobao.compose.yaml b/deploy/storyforge-server-huobao.compose.yaml new file mode 100644 index 0000000..1893ada --- /dev/null +++ b/deploy/storyforge-server-huobao.compose.yaml @@ -0,0 +1,25 @@ +services: + storyforge-huobao: + image: ${STORYFORGE_HUOBAO_IMAGE:-storyforge-huobao:cloud} + build: + context: ../../huobao-drama-source + dockerfile: Dockerfile + args: + DOCKER_REGISTRY: ${STORYFORGE_HUOBAO_DOCKER_REGISTRY:-docker.m.daocloud.io/library/} + NPM_REGISTRY: ${STORYFORGE_HUOBAO_NPM_REGISTRY:-https://registry.npmmirror.com} + GO_PROXY: ${STORYFORGE_HUOBAO_GO_PROXY:-https://goproxy.cn,direct} + ALPINE_MIRROR: ${STORYFORGE_HUOBAO_ALPINE_MIRROR:-mirrors.aliyun.com} + container_name: storyforge-huobao + restart: unless-stopped + ports: + - "${STORYFORGE_HUOBAO_PORT:-127.0.0.1:25678:5678}" + environment: + TZ: ${TZ:-Asia/Shanghai} + volumes: + - "${STORYFORGE_HUOBAO_STATE_ROOT:-/home/ubuntu/storyforge/data/huobao}/data:/app/data" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5678/health"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 20s diff --git a/deploy/storyforge-server-n8n.compose.yaml b/deploy/storyforge-server-n8n.compose.yaml new file mode 100644 index 0000000..097d3c8 --- /dev/null +++ b/deploy/storyforge-server-n8n.compose.yaml @@ -0,0 +1,27 @@ +services: + storyforge-n8n: + image: ${STORYFORGE_N8N_IMAGE:-docker.m.daocloud.io/n8nio/n8n:latest} + container_name: storyforge-n8n + restart: unless-stopped + ports: + - "${STORYFORGE_N8N_PORT:-127.0.0.1:25670:5678}" + environment: + N8N_HOST: ${N8N_HOST:-0.0.0.0} + N8N_PORT: 5678 + N8N_PROTOCOL: ${N8N_PROTOCOL:-https} + WEBHOOK_URL: ${WEBHOOK_URL:-https://storyforge.hyzq.net/} + STORYFORGE_INTERNAL_BASE_URL: ${STORYFORGE_INTERNAL_BASE_URL:-http://127.0.0.1:8081} + STORYFORGE_ORCHESTRATOR_SECRET: ${ORCHESTRATOR_SHARED_SECRET:-storyforge-local-secret} + GENERIC_TIMEZONE: ${GENERIC_TIMEZONE:-Asia/Shanghai} + TZ: ${TZ:-Asia/Shanghai} + N8N_SECURE_COOKIE: ${N8N_SECURE_COOKIE:-false} + N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: ${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS:-false} + volumes: + - "${STORYFORGE_N8N_STATE_ROOT:-/home/ubuntu/storyforge/data/n8n}:/home/node/.n8n" + - "${STORYFORGE_N8N_WORKFLOW_ROOT:-/home/ubuntu/storyforge/n8n}:/workspace/n8n:ro" + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5678/healthz"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 20s diff --git a/scripts/deploy_server_storyforge_huobao.sh b/scripts/deploy_server_storyforge_huobao.sh new file mode 100755 index 0000000..1288734 --- /dev/null +++ b/scripts/deploy_server_storyforge_huobao.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)" +REMOTE_HOST="${AG_HOST:-111.231.132.51}" +REMOTE_USER="${AG_USER:-ubuntu}" +REMOTE_ROOT="${STORYFORGE_SERVER_REMOTE_ROOT:-/home/ubuntu/storyforge}" +REMOTE_COMPOSE_DIR="$REMOTE_ROOT/deploy/cloud" +REMOTE_STATE_ROOT="${STORYFORGE_HUOBAO_STATE_ROOT:-$REMOTE_ROOT/data/huobao}" +LOCAL_SOURCE_ROOT="${STORYFORGE_HUOBAO_SOURCE_ROOT:-/Users/kris/code/huobao-drama-upstream}" +HUOBAO_PORT="${STORYFORGE_HUOBAO_PORT:-127.0.0.1:25678:5678}" + +PW="${AG_SERVER_PASSWORD:-$(security find-generic-password -a "$REMOTE_USER" -s ai-glasses-debug-ssh -w)}" +TMPDIR_DEPLOY="$(mktemp -d)" +trap 'rm -rf "$TMPDIR_DEPLOY"' EXIT + +FILTERED_SOURCE="$TMPDIR_DEPLOY/huobao-drama-source" +mkdir -p "$FILTERED_SOURCE" "$TMPDIR_DEPLOY/state/data" +rsync -a \ + --exclude '.git' \ + --exclude 'data' \ + --exclude 'web/node_modules' \ + --exclude 'web/dist' \ + --exclude '.DS_Store' \ + "$LOCAL_SOURCE_ROOT/" "$FILTERED_SOURCE/" +if [ -f "$LOCAL_SOURCE_ROOT/data/drama.db" ]; then + cp "$LOCAL_SOURCE_ROOT/data/drama.db" "$TMPDIR_DEPLOY/state/data/drama.db" +fi + +sshpass -p "$PW" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$REMOTE_USER@$REMOTE_HOST" \ + "mkdir -p '$REMOTE_COMPOSE_DIR' '$REMOTE_ROOT/huobao-drama-source' '$REMOTE_STATE_ROOT/data'" +sshpass -p "$PW" scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "$ROOT/deploy/storyforge-server-huobao.compose.yaml" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_COMPOSE_DIR/storyforge-server-huobao.compose.yaml" +sshpass -p "$PW" rsync -a -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ + "$FILTERED_SOURCE/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_ROOT/huobao-drama-source/" +sshpass -p "$PW" rsync -a -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ + "$TMPDIR_DEPLOY/state/data/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_STATE_ROOT/data/" + +sshpass -p "$PW" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$REMOTE_USER@$REMOTE_HOST" \ + "sudo sh -lc 'cd \"$REMOTE_COMPOSE_DIR\" && STORYFORGE_HUOBAO_PORT=\"$HUOBAO_PORT\" STORYFORGE_HUOBAO_IMAGE=storyforge-huobao:cloud docker compose -f storyforge-server-huobao.compose.yaml up -d --build --force-recreate storyforge-huobao'" + +sshpass -p "$PW" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$REMOTE_USER@$REMOTE_HOST" \ + "curl -fsS --max-time 30 http://127.0.0.1:25678/health >/dev/null" + +echo "cloud huobao deployed: http://127.0.0.1:25678/health" diff --git a/scripts/deploy_server_storyforge_n8n.sh b/scripts/deploy_server_storyforge_n8n.sh new file mode 100755 index 0000000..fc0f231 --- /dev/null +++ b/scripts/deploy_server_storyforge_n8n.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)" +REMOTE_HOST="${AG_HOST:-111.231.132.51}" +REMOTE_USER="${AG_USER:-ubuntu}" +REMOTE_ROOT="${STORYFORGE_SERVER_REMOTE_ROOT:-/home/ubuntu/storyforge}" +REMOTE_COMPOSE_DIR="$REMOTE_ROOT/deploy/cloud" +REMOTE_STATE_ROOT="${STORYFORGE_N8N_STATE_ROOT:-$REMOTE_ROOT/data/n8n}" +N8N_PORT="${STORYFORGE_N8N_PORT:-127.0.0.1:25670:5678}" + +PW="${AG_SERVER_PASSWORD:-$(security find-generic-password -a "$REMOTE_USER" -s ai-glasses-debug-ssh -w)}" +TMPDIR_DEPLOY="$(mktemp -d)" +trap 'rm -rf "$TMPDIR_DEPLOY"' EXIT + +mkdir -p "$TMPDIR_DEPLOY/data" +rsync -a "$ROOT/data/n8n/" "$TMPDIR_DEPLOY/data/" + +sshpass -p "$PW" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$REMOTE_USER@$REMOTE_HOST" \ + "mkdir -p '$REMOTE_COMPOSE_DIR' '$REMOTE_ROOT/n8n' '$REMOTE_STATE_ROOT'" +sshpass -p "$PW" scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + "$ROOT/deploy/storyforge-server-n8n.compose.yaml" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_COMPOSE_DIR/storyforge-server-n8n.compose.yaml" +sshpass -p "$PW" rsync -a -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ + "$ROOT/n8n/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_ROOT/n8n/" +sshpass -p "$PW" rsync -a -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" \ + "$TMPDIR_DEPLOY/data/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_STATE_ROOT/" + +sshpass -p "$PW" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$REMOTE_USER@$REMOTE_HOST" \ + "sudo sh -lc 'cd \"$REMOTE_COMPOSE_DIR\" && STORYFORGE_N8N_PORT=\"$N8N_PORT\" docker compose -f storyforge-server-n8n.compose.yaml up -d --force-recreate storyforge-n8n'" + +sshpass -p "$PW" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$REMOTE_USER@$REMOTE_HOST" \ + "curl -fsS --max-time 20 http://127.0.0.1:25670/healthz >/dev/null" + +echo "cloud n8n deployed: http://127.0.0.1:25670/healthz"