deploy: switch public entry to storyforge.hyzq.net

This commit is contained in:
kris
2026-03-23 18:19:52 +08:00
parent f093f72ae4
commit 17b419f8ef
14 changed files with 147 additions and 121 deletions

View File

@@ -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 录制` 继续由本机和局域网执行链提供
## 说明

View File

@@ -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

View File

@@ -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\"")
}

View File

@@ -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(

View File

@@ -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
}

View File

@@ -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

View File

@@ -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", "")

View File

@@ -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:-}"

View File

@@ -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/*`
## 当前优点

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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:-}

View File

@@ -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`
## 后续建议

View File

@@ -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`;
}