From 17b419f8efd714d03d89c460a968fd4089b3bd4a Mon Sep 17 00:00:00 2001 From: kris Date: Mon, 23 Mar 2026 18:19:52 +0800 Subject: [PATCH] deploy: switch public entry to storyforge.hyzq.net --- README.md | 8 +- android-app/README.md | 2 +- android-app/app/build.gradle.kts | 2 +- .../app/storyforge/StoryForgeRepository.kt | 6 +- .../app/storyforge/StoryForgeSessionStore.kt | 2 + .../com/aiglasses/app/ui/MainViewModel.kt | 2 +- collector-service/app/core_main.py | 2 +- collector-service/run_source_overlay.sh | 2 +- ...ATEWAY.md => STORYFORGE_PUBLIC_GATEWAY.md} | 13 +- deploy/storyforge-hyzq-net-nginx.conf | 117 ++++++++++++++++++ .../storyforge-test-hyzq-nginx.conf.fragment | 101 --------------- docker-compose.yml | 2 +- web/storyforge-web-v4/README.md | 6 +- web/storyforge-web-v4/assets/app.js | 3 + 14 files changed, 147 insertions(+), 121 deletions(-) rename deploy/{STORYFORGE_TEST_HYZQ_GATEWAY.md => STORYFORGE_PUBLIC_GATEWAY.md} (77%) create mode 100644 deploy/storyforge-hyzq-net-nginx.conf delete mode 100644 deploy/storyforge-test-hyzq-nginx.conf.fragment diff --git a/README.md b/README.md index bbdd42d..8a3d00c 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ N8N_BASE_URL=http://127.0.0.1:5670 - `collector-service`:`http://127.0.0.1:8081` - `n8n`:`http://127.0.0.1:5670` - `cli-proxy-api`:`http://127.0.0.1:8317` -- 公网入口:`https://test.hyzq.net/storyforge/` +- 公网入口:`https://storyforge.hyzq.net/` 默认会创建最高权限账号: @@ -153,9 +153,9 @@ N8N_BASE_URL=http://127.0.0.1:5670 - 触发 `ai_video_pipeline` - 历史旧运行链已完成移除,当前运行时只保留 StoryForge 自身服务与外部执行引擎 - 当前公网接入采用“云服务器 HTTPS 入口 + 本机桥接隧道 + 本机现网执行链”模式: - - `https://test.hyzq.net/storyforge/` 由云服务器 `nginx` 提供 HTTPS 入口 - - `/storyforge/` 静态页反向代理到本机 `Web V4` 静态服务 - - `/storyforge/v2/*`、`/storyforge/openapi.json`、`/storyforge/healthz` 反向代理到本机 `collector-service` + - `https://storyforge.hyzq.net/` 由云服务器 `nginx` 提供 HTTPS 入口 + - `/` 静态页由云服务器本地 `StoryForge Web V4` 直出 + - `/v2/*`、`/openapi.json`、`/healthz` 反向代理到本机 `collector-service` - `cutvideo / huobao / 本机模型 / NAS 录制` 继续由本机和局域网执行链提供 ## 说明 diff --git a/android-app/README.md b/android-app/README.md index 955c958..40f308a 100644 --- a/android-app/README.md +++ b/android-app/README.md @@ -25,7 +25,7 @@ Demo Android client for backend API validation and BLE integration scaffold. The app is hardcoded to: -`http://test.hyzq.net` +`https://storyforge.hyzq.net` ## Build APK diff --git a/android-app/app/build.gradle.kts b/android-app/app/build.gradle.kts index 2bb5545..fb9a458 100644 --- a/android-app/app/build.gradle.kts +++ b/android-app/app/build.gradle.kts @@ -16,7 +16,7 @@ android { versionName = "0.6.4" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - buildConfigField("String", "DEFAULT_STORYFORGE_BASE_URL", "\"https://test.hyzq.net/storyforge\"") + buildConfigField("String", "DEFAULT_STORYFORGE_BASE_URL", "\"https://storyforge.hyzq.net\"") buildConfigField("String", "DEFAULT_STORYFORGE_FALLBACK_IP", "\"111.231.132.51\"") buildConfigField("String", "DEFAULT_LOCAL_MODEL_BASE_URL", "\"http://127.0.0.1:8317/v1\"") } diff --git a/android-app/app/src/main/java/com/aiglasses/app/storyforge/StoryForgeRepository.kt b/android-app/app/src/main/java/com/aiglasses/app/storyforge/StoryForgeRepository.kt index bc54d9e..9c75afb 100644 --- a/android-app/app/src/main/java/com/aiglasses/app/storyforge/StoryForgeRepository.kt +++ b/android-app/app/src/main/java/com/aiglasses/app/storyforge/StoryForgeRepository.kt @@ -286,6 +286,7 @@ class StoryForgeRepository(private val context: Context) { val trimmed = baseUrl.trim().ifBlank { BuildConfig.DEFAULT_STORYFORGE_BASE_URL } val migrated = when { trimmed.startsWith("http://test.hyzq.net:8081") -> BuildConfig.DEFAULT_STORYFORGE_BASE_URL + trimmed.startsWith("https://test.hyzq.net/storyforge") -> BuildConfig.DEFAULT_STORYFORGE_BASE_URL trimmed.startsWith("http://111.231.132.51:8081") -> BuildConfig.DEFAULT_STORYFORGE_BASE_URL else -> trimmed } @@ -312,7 +313,10 @@ class StoryForgeRepository(private val context: Context) { .takeUnless { isInvalidResolvedIp(it) } .orEmpty() .ifBlank { - if (host.equals("test.hyzq.net", ignoreCase = true)) BuildConfig.DEFAULT_STORYFORGE_FALLBACK_IP else "" + if ( + host.equals("test.hyzq.net", ignoreCase = true) || + host.equals("storyforge.hyzq.net", ignoreCase = true) + ) BuildConfig.DEFAULT_STORYFORGE_FALLBACK_IP else "" } if (resolvedIp.isBlank()) { return StoryForgeConnectionInfo( diff --git a/android-app/app/src/main/java/com/aiglasses/app/storyforge/StoryForgeSessionStore.kt b/android-app/app/src/main/java/com/aiglasses/app/storyforge/StoryForgeSessionStore.kt index e308fd4..cd95c4e 100644 --- a/android-app/app/src/main/java/com/aiglasses/app/storyforge/StoryForgeSessionStore.kt +++ b/android-app/app/src/main/java/com/aiglasses/app/storyforge/StoryForgeSessionStore.kt @@ -44,6 +44,7 @@ class StoryForgeSessionStore(context: Context) { private const val KEY_BASE_URL = "base_url" private const val KEY_TOKEN = "token" private const val LEGACY_DOMAIN_URL = "http://test.hyzq.net:8081" + private const val LEGACY_PUBLIC_URL = "https://test.hyzq.net/storyforge" private const val LEGACY_IP_URL = "http://111.231.132.51:8081" } @@ -52,6 +53,7 @@ class StoryForgeSessionStore(context: Context) { return when { trimmed.isBlank() -> BuildConfig.DEFAULT_STORYFORGE_BASE_URL trimmed.startsWith(LEGACY_DOMAIN_URL) -> BuildConfig.DEFAULT_STORYFORGE_BASE_URL + trimmed.startsWith(LEGACY_PUBLIC_URL) -> BuildConfig.DEFAULT_STORYFORGE_BASE_URL trimmed.startsWith(LEGACY_IP_URL) -> BuildConfig.DEFAULT_STORYFORGE_BASE_URL else -> trimmed } diff --git a/android-app/app/src/main/java/com/aiglasses/app/ui/MainViewModel.kt b/android-app/app/src/main/java/com/aiglasses/app/ui/MainViewModel.kt index 53da594..c3c5796 100644 --- a/android-app/app/src/main/java/com/aiglasses/app/ui/MainViewModel.kt +++ b/android-app/app/src/main/java/com/aiglasses/app/ui/MainViewModel.kt @@ -95,7 +95,7 @@ private data class PendingRemoteLog( class MainViewModel(application: Application) : AndroidViewModel(application) { companion object { - private const val BACKEND_BASE_URL = "https://test.hyzq.net" + private const val BACKEND_BASE_URL = "https://storyforge.hyzq.net" private const val REMOTE_LOG_PREFS = "remote_log_queue" private const val REMOTE_LOG_KEY_QUEUE = "pending_events_json" private const val REMOTE_LOG_MAX_PENDING = 400 diff --git a/collector-service/app/core_main.py b/collector-service/app/core_main.py index 2f66c13..487596d 100644 --- a/collector-service/app/core_main.py +++ b/collector-service/app/core_main.py @@ -32,7 +32,7 @@ DOWNLOADS_DIR = Path(os.getenv("DOWNLOADS_DIR", str(DATA_DIR / "downloads"))) JOBS_DIR = Path(os.getenv("JOBS_DIR", str(DATA_DIR / "jobs"))) MODELS_DIR = Path(os.getenv("MODELS_DIR", str(DATA_DIR / "models"))) DB_PATH = os.getenv("DATABASE_PATH", str(DATA_DIR / "storyforge.db")) -DEFAULT_EXTERNAL_BASE_URL = os.getenv("DEFAULT_EXTERNAL_BASE_URL", "https://test.hyzq.net/storyforge") +DEFAULT_EXTERNAL_BASE_URL = os.getenv("DEFAULT_EXTERNAL_BASE_URL", "https://storyforge.hyzq.net") LOCAL_OPENAI_BASE_URL = os.getenv("LOCAL_OPENAI_BASE_URL", "http://127.0.0.1:8317/v1") LOCAL_OPENAI_MODEL = os.getenv("LOCAL_OPENAI_MODEL", "GLM-5") LOCAL_OPENAI_API_KEY = os.getenv("LOCAL_OPENAI_API_KEY", "") diff --git a/collector-service/run_source_overlay.sh b/collector-service/run_source_overlay.sh index c132678..8b1199d 100755 --- a/collector-service/run_source_overlay.sh +++ b/collector-service/run_source_overlay.sh @@ -9,7 +9,7 @@ HOST="${HOST:-127.0.0.1}" # against the same database and external integrations without touching 8081. export DATA_DIR="${DATA_DIR:-/Users/kris/code/StoryForge-gitea/data/collector}" export DATABASE_PATH="${DATABASE_PATH:-$DATA_DIR/storyforge.db}" -export DEFAULT_EXTERNAL_BASE_URL="${DEFAULT_EXTERNAL_BASE_URL:-https://test.hyzq.net/storyforge}" +export DEFAULT_EXTERNAL_BASE_URL="${DEFAULT_EXTERNAL_BASE_URL:-https://storyforge.hyzq.net}" export LOCAL_OPENAI_BASE_URL="${LOCAL_OPENAI_BASE_URL:-http://host.docker.internal:8317/v1}" export LOCAL_OPENAI_MODEL="${LOCAL_OPENAI_MODEL:-GLM-5}" export LOCAL_OPENAI_API_KEY="${LOCAL_OPENAI_API_KEY:-}" diff --git a/deploy/STORYFORGE_TEST_HYZQ_GATEWAY.md b/deploy/STORYFORGE_PUBLIC_GATEWAY.md similarity index 77% rename from deploy/STORYFORGE_TEST_HYZQ_GATEWAY.md rename to deploy/STORYFORGE_PUBLIC_GATEWAY.md index 0dc29d5..2de74c9 100644 --- a/deploy/STORYFORGE_TEST_HYZQ_GATEWAY.md +++ b/deploy/STORYFORGE_PUBLIC_GATEWAY.md @@ -1,8 +1,8 @@ -# StoryForge `test.hyzq.net/storyforge` 公网入口 +# StoryForge `storyforge.hyzq.net` 公网入口 当前公网接入不是把执行链整体迁到云服务器,而是: -1. 云服务器 `nginx` 提供 `https://test.hyzq.net/storyforge/` +1. 云服务器 `nginx` 提供 `https://storyforge.hyzq.net/` 2. 云服务器本地 `storyforge-web-v4.service` 承接静态前端 3. 本机 `collector-service` 继续承接业务与局域网执行引擎 4. 本机通过 SSH 反向隧道只桥接 API 到云服务器 @@ -20,10 +20,11 @@ ## 云服务器 `nginx` 路由 -- `/storyforge/` -> `127.0.0.1:19191` -- `/storyforge/v2/*` -> `127.0.0.1:18181` -- `/storyforge/openapi.json` -> `127.0.0.1:18181/openapi.json` -- `/storyforge/healthz` -> `127.0.0.1:18181/healthz` +- `/` -> `127.0.0.1:19191` +- `/v2/*` -> `127.0.0.1:18181` +- `/openapi.json` -> `127.0.0.1:18181/openapi.json` +- `/healthz` -> `127.0.0.1:18181/healthz` +- `/downloads/*` -> `127.0.0.1:18181/downloads/*` ## 当前优点 diff --git a/deploy/storyforge-hyzq-net-nginx.conf b/deploy/storyforge-hyzq-net-nginx.conf new file mode 100644 index 0000000..acf5010 --- /dev/null +++ b/deploy/storyforge-hyzq-net-nginx.conf @@ -0,0 +1,117 @@ +server { + listen 80; + listen [::]:80; + server_name storyforge.hyzq.net; + + location ^~ /.well-known/acme-challenge/ { + root /var/www/certbot; + default_type text/plain; + } + + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name storyforge.hyzq.net; + + ssl_certificate /etc/letsencrypt/live/storyforge.hyzq.net/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/storyforge.hyzq.net/privkey.pem; + + location = /healthz { + auth_basic off; + proxy_pass http://127.0.0.1:18181/healthz; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location = /openapi.json { + auth_basic off; + proxy_pass http://127.0.0.1:18181/openapi.json; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location = /api/v1/app/update/latest { + auth_basic off; + proxy_pass http://127.0.0.1:18181/api/v1/app/update/latest; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location ^~ /downloads/ { + auth_basic off; + proxy_pass http://127.0.0.1:18181/downloads/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + } + + location ^~ /v2/ { + auth_basic off; + proxy_pass http://127.0.0.1:18181/v2/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + } + + location ^~ /docs { + auth_basic off; + proxy_pass http://127.0.0.1:18181; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + } + + location ^~ /redoc { + auth_basic off; + proxy_pass http://127.0.0.1:18181; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + } + + location / { + auth_basic off; + proxy_pass http://127.0.0.1:19191/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 300s; + proxy_send_timeout 300s; + proxy_buffering off; + } +} diff --git a/deploy/storyforge-test-hyzq-nginx.conf.fragment b/deploy/storyforge-test-hyzq-nginx.conf.fragment deleted file mode 100644 index 554601a..0000000 --- a/deploy/storyforge-test-hyzq-nginx.conf.fragment +++ /dev/null @@ -1,101 +0,0 @@ -location = /storyforge { - auth_basic off; - return 301 /storyforge/; -} - -location = /storyforge/healthz { - auth_basic off; - proxy_pass http://127.0.0.1:18181/healthz; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; -} - -location = /storyforge/openapi.json { - auth_basic off; - proxy_pass http://127.0.0.1:18181/openapi.json; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; -} - -location = /storyforge/api/v1/app/update/latest { - auth_basic off; - proxy_pass http://127.0.0.1:18181/api/v1/app/update/latest; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; -} - -location ^~ /storyforge/downloads/ { - auth_basic off; - proxy_pass http://127.0.0.1:18181/downloads/; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_read_timeout 300s; - proxy_send_timeout 300s; -} - -location ^~ /storyforge/v2/ { - auth_basic off; - proxy_pass http://127.0.0.1:18181/v2/; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_read_timeout 300s; - proxy_send_timeout 300s; - proxy_buffering off; -} - -location ^~ /storyforge/docs { - auth_basic off; - rewrite ^/storyforge(/docs.*)$ $1 break; - proxy_pass http://127.0.0.1:18181; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_read_timeout 300s; - proxy_send_timeout 300s; - proxy_buffering off; -} - -location ^~ /storyforge/redoc { - auth_basic off; - rewrite ^/storyforge(/redoc.*)$ $1 break; - proxy_pass http://127.0.0.1:18181; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_read_timeout 300s; - proxy_send_timeout 300s; - proxy_buffering off; -} - -location ^~ /storyforge/ { - auth_basic off; - rewrite ^/storyforge/?(.*)$ /$1 break; - proxy_pass http://127.0.0.1:18191; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_read_timeout 300s; - proxy_send_timeout 300s; - proxy_buffering off; -} diff --git a/docker-compose.yml b/docker-compose.yml index 83f0332..c042683 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,7 +28,7 @@ services: environment: DATA_DIR: /data/collector DATABASE_PATH: /data/collector/storyforge.db - DEFAULT_EXTERNAL_BASE_URL: ${DEFAULT_EXTERNAL_BASE_URL:-https://test.hyzq.net/storyforge} + DEFAULT_EXTERNAL_BASE_URL: ${DEFAULT_EXTERNAL_BASE_URL:-https://storyforge.hyzq.net} LOCAL_OPENAI_BASE_URL: ${LOCAL_OPENAI_BASE_URL:-http://host.docker.internal:8317/v1} LOCAL_OPENAI_MODEL: ${LOCAL_OPENAI_MODEL:-GLM-5} LOCAL_OPENAI_API_KEY: ${LOCAL_OPENAI_API_KEY:-} diff --git a/web/storyforge-web-v4/README.md b/web/storyforge-web-v4/README.md index 1fbb2fd..b3b1e67 100644 --- a/web/storyforge-web-v4/README.md +++ b/web/storyforge-web-v4/README.md @@ -14,7 +14,7 @@ - 目录已经从 `output/ui/` 原型区独立出来,并接上了第一层真实业务接口 - 这里面向国内平台的 Web 承载,当前覆盖 `douyin`、`xiaohongshu`、`bilibili`、`kuaishou`、`wechat_video` - `YouTube` 目前明确不在本轮范围内 -- 已支持通过 `https://test.hyzq.net/storyforge/` 做公网访问 +- 已支持通过 `https://storyforge.hyzq.net/` 做公网访问 - 通用的项目、内容源、复盘、集成等流程可以正常使用 - 平台工作台和运行时数据目前只有 `douyin` 做到了完整实现,其余平台统一按 `待接入工作台` 处理 - 当前保留的核心页面结构: @@ -102,11 +102,11 @@ python3 -m http.server 3918 如果页面部署在: -- `https://test.hyzq.net/storyforge/` +- `https://storyforge.hyzq.net/` 前端会自动把默认后端切到同源的: -- `https://test.hyzq.net/storyforge` +- `https://storyforge.hyzq.net` ## 后续建议 diff --git a/web/storyforge-web-v4/assets/app.js b/web/storyforge-web-v4/assets/app.js index 29d0620..400ea08 100644 --- a/web/storyforge-web-v4/assets/app.js +++ b/web/storyforge-web-v4/assets/app.js @@ -5,6 +5,9 @@ function detectDefaultBackendUrl() { return "http://127.0.0.1:8081"; } const { origin, hostname, port, pathname } = window.location; + if (/^https?:/i.test(origin) && hostname === "storyforge.hyzq.net") { + return origin; + } if (/^https?:/i.test(origin) && pathname.startsWith("/storyforge")) { return `${origin}/storyforge`; }