fix: avoid production spacetimedb port conflict
This commit is contained in:
2
deploy/env/api-server.env.example
vendored
2
deploy/env/api-server.env.example
vendored
@@ -22,7 +22,7 @@ AUTH_REFRESH_COOKIE_SECURE=true
|
||||
GENARRATIVE_AUTH_STORE_PATH=/var/lib/genarrative/auth/auth-store.json
|
||||
GENARRATIVE_DEV_PASSWORD_ENTRY_AUTO_REGISTER_ENABLED=false
|
||||
|
||||
GENARRATIVE_SPACETIME_SERVER_URL=http://127.0.0.1:3000
|
||||
GENARRATIVE_SPACETIME_SERVER_URL=http://127.0.0.1:3101
|
||||
GENARRATIVE_SPACETIME_DATABASE=genarrative-prod
|
||||
GENARRATIVE_SPACETIME_TOKEN=
|
||||
GENARRATIVE_SPACETIME_POOL_SIZE=8
|
||||
|
||||
@@ -55,7 +55,7 @@ server {
|
||||
|
||||
# 仅开放前端 SpacetimeDB SDK 运行所需的最小公网路由。
|
||||
location ~ ^/v1/database/[^/]+/subscribe$ {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_pass http://127.0.0.1:3101;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
@@ -64,7 +64,7 @@ server {
|
||||
}
|
||||
|
||||
location ^~ /v1/identity {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_pass http://127.0.0.1:3101;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
|
||||
@@ -69,7 +69,7 @@ server {
|
||||
|
||||
# SpacetimeDB 只开放 TypeScript SDK 运行所需的最小公网路由。
|
||||
location ~ ^/v1/database/[^/]+/subscribe$ {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_pass http://127.0.0.1:3101;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
@@ -78,7 +78,7 @@ server {
|
||||
}
|
||||
|
||||
location ^~ /v1/identity {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_pass http://127.0.0.1:3101;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
|
||||
@@ -8,7 +8,7 @@ Type=simple
|
||||
User=spacetimedb
|
||||
Group=spacetimedb
|
||||
WorkingDirectory=/stdb
|
||||
ExecStart=/stdb/spacetime --root-dir=/stdb start --listen-addr=127.0.0.1:3000
|
||||
ExecStart=/stdb/spacetime --root-dir=/stdb start --listen-addr=127.0.0.1:3101
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
LimitNOFILE=1048576
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
## 生产架构
|
||||
|
||||
- Nginx 作为唯一公网入口,负责 HTTPS、静态站点、后台静态页面、维护页与 `/admin/api/` 反向代理。
|
||||
- SpacetimeDB 作为系统服务运行,监听 `127.0.0.1:3000`,数据根目录为 `/stdb`。
|
||||
- SpacetimeDB 作为系统服务运行,监听 `127.0.0.1:3101`,数据根目录为 `/stdb`。`3000` 保留给部署机本机 Git/Web 服务,禁止再让 SpacetimeDB 占用该端口。
|
||||
- Rust `api-server` 作为系统服务运行,监听 `127.0.0.1:8082`,只被 Nginx 的 `/admin/api/` 访问。
|
||||
- 主站与后台前端构建为静态文件,发布到服务器固定目录,不放入 Jenkins 目录,也不跟随 Docker 镜像。
|
||||
- 除网站静态发布外,`api-server` 发布、SpacetimeDB 模块发布、数据库导入、服务器配置变更都必须先进入维护模式。
|
||||
@@ -77,7 +77,7 @@
|
||||
- 服务名:`spacetimedb.service`
|
||||
- 运行用户:`spacetimedb`
|
||||
- 工作目录:`/stdb`
|
||||
- 启动命令:`/stdb/spacetime --root-dir=/stdb start --listen-addr=127.0.0.1:3000`
|
||||
- 启动命令:`/stdb/spacetime --root-dir=/stdb start --listen-addr=127.0.0.1:3101`
|
||||
- 对外暴露:默认不直接暴露公网端口。
|
||||
|
||||
该方案与 SpacetimeDB 官方自托管文档一致:使用 Ubuntu、专用用户、`/stdb` 根目录、systemd 服务和 Nginx。
|
||||
@@ -210,6 +210,7 @@ Jenkins controller 与 Linux agent 看到的 Git 服务地址不同,必须拆
|
||||
|
||||
- Jenkins Job 的 `Pipeline script from SCM` 由 controller 执行,SCM URL 使用 controller 可访问的公网地址:`http://82.157.175.59:3000/GenarrativeAI/Genarrative.git`。
|
||||
- Jenkinsfile 内部的源码、脚本 checkout 在 Linux agent 上执行,`GIT_REMOTE_URL` 使用 agent 本机可访问地址:`http://127.0.0.1:3000/GenarrativeAI/Genarrative.git`。
|
||||
- 这里的 `3000` 是 Git/Web 服务端口,不是 SpacetimeDB 端口;生产 SpacetimeDB 固定使用 `http://127.0.0.1:3101`,避免流水线部署时与本机 Git 服务抢端口。
|
||||
|
||||
因此生产 Jenkinsfile 不使用 `checkout scm` 作为构建源码入口,而是显式 `checkout([$class: 'GitSCM', userRemoteConfigs: [[url: "${GIT_REMOTE_URL}"]], ...])`。后续 `scripts/jenkins-checkout-source.sh` 会继续把 `origin` 设置为 `GIT_REMOTE_URL`,并按 `SOURCE_BRANCH` / `COMMIT_HASH` 拉取和校验目标提交。
|
||||
|
||||
@@ -474,7 +475,7 @@ WASM_SOURCE="${CARGO_TARGET_DIR}/wasm32-unknown-unknown/release/spacetime_module
|
||||
- 通过 `DEPLOY_TARGET` 选择逻辑导出目标;`development` 映射到 `linux && genarrative-build`,`release` 映射到 `linux && genarrative-release-deploy`。
|
||||
- `release` 导出必须勾选 `CONFIRM_RELEASE_DEPLOY_AGENT`,避免当前开发/构建/开发部署 agent 冒充 release 部署机。
|
||||
- 进入维护模式,避免导出期间继续写入。
|
||||
- 从目标机器本机 SpacetimeDB 导出指定数据库数据,默认连接 `SPACETIME_SERVER=local`,自托管 `root-dir` 默认 `/stdb`。
|
||||
- 从目标机器本机 SpacetimeDB 导出指定数据库数据,默认连接 `SPACETIME_SERVER_URL=http://127.0.0.1:3101`,自托管 `root-dir` 默认 `/stdb`。
|
||||
- 产物归档到 Jenkins,并可额外保存到 `SERVER_BACKUP_DIRECTORY`。
|
||||
- 敏感 token 与 bootstrap secret 只通过 Jenkins Secret Text 凭据 ID 注入,不作为明文 Job 参数。
|
||||
- 成功后解除维护模式。
|
||||
|
||||
@@ -19,7 +19,7 @@ pipeline {
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins Secret Text 凭据 genarrative-notification-emails 合并发送')
|
||||
string(name: 'DATABASE', defaultValue: 'genarrative-prod', description: 'SpacetimeDB database')
|
||||
string(name: 'SPACETIME_SERVER', defaultValue: 'local', description: 'SpacetimeDB server alias')
|
||||
string(name: 'SPACETIME_SERVER_URL', defaultValue: '', description: '显式 SpacetimeDB server URL,填写后优先于 SPACETIME_SERVER')
|
||||
string(name: 'SPACETIME_SERVER_URL', defaultValue: 'http://127.0.0.1:3101', description: '显式 SpacetimeDB server URL,填写后优先于 SPACETIME_SERVER')
|
||||
string(name: 'SPACETIME_ROOT_DIR', defaultValue: '/stdb', description: 'spacetime CLI root-dir;release 自托管默认 /stdb')
|
||||
string(name: 'INCLUDE_TABLES', defaultValue: '', description: '可选,逗号分隔的表名白名单')
|
||||
string(name: 'WORKSPACE_EXPORT_DIRECTORY', defaultValue: 'database-exports', description: 'Jenkins workspace 内的导出目录,用于归档')
|
||||
|
||||
@@ -19,7 +19,7 @@ pipeline {
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins Secret Text 凭据 genarrative-notification-emails 合并发送')
|
||||
string(name: 'DATABASE', defaultValue: 'genarrative-prod', description: 'SpacetimeDB database')
|
||||
string(name: 'SPACETIME_SERVER', defaultValue: 'local', description: 'SpacetimeDB server alias')
|
||||
string(name: 'SPACETIME_SERVER_URL', defaultValue: '', description: '显式 SpacetimeDB server URL,填写后优先于 SPACETIME_SERVER')
|
||||
string(name: 'SPACETIME_SERVER_URL', defaultValue: 'http://127.0.0.1:3101', description: '显式 SpacetimeDB server URL,填写后优先于 SPACETIME_SERVER')
|
||||
string(name: 'SPACETIME_ROOT_DIR', defaultValue: '/stdb', description: 'spacetime CLI root-dir;release 自托管默认 /stdb')
|
||||
choice(name: 'INPUT_SOURCE', choices: ['pipeline_archive', 'manual_upload'], description: '导入数据源;pipeline_archive 从导出流水线归档获取,manual_upload 使用本次构建手动上传文件')
|
||||
string(name: 'INPUT_FILE', defaultValue: '', description: 'pipeline_archive 模式可选;留空时使用导出流水线默认归档路径 database-exports/spacetime-migration-<导出构建号>.json')
|
||||
|
||||
@@ -30,6 +30,7 @@ pipeline {
|
||||
choice(name: 'DEPLOY_TARGET', choices: ['development', 'release'], description: '逻辑部署目标;development 使用当前 Linux 开发/构建/开发部署 agent')
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', defaultValue: false, description: '确认 release 目标已有独立 release 部署 agent;当前 Linux 开发/构建/开发部署 agent 不可冒充 release 部署机')
|
||||
string(name: 'DATABASE', defaultValue: 'genarrative-prod', description: '生产 SpacetimeDB database')
|
||||
string(name: 'SPACETIME_SERVER_URL', defaultValue: 'http://127.0.0.1:3101', description: 'Stdb 发布目标 URL;默认避开本机 Git/Web 使用的 3000 端口')
|
||||
}
|
||||
|
||||
stages {
|
||||
@@ -134,6 +135,7 @@ pipeline {
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION),
|
||||
string(name: 'NOTIFICATION_EMAILS', value: params.NOTIFICATION_EMAILS ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE),
|
||||
string(name: 'SPACETIME_SERVER_URL', value: params.SPACETIME_SERVER_URL ?: ''),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET),
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', value: params.CONFIRM_RELEASE_DEPLOY_AGENT),
|
||||
string(name: 'BUILD_JOB_NAME', value: params.STDB_BUILD_JOB_NAME),
|
||||
|
||||
@@ -185,7 +185,7 @@ pipeline {
|
||||
render_api_env_example() {
|
||||
sed \
|
||||
-e "s|^GENARRATIVE_API_PORT=.*|GENARRATIVE_API_PORT=${API_PORT}|" \
|
||||
-e "s|^GENARRATIVE_SPACETIME_SERVER_URL=.*|GENARRATIVE_SPACETIME_SERVER_URL=http://127.0.0.1:3000|" \
|
||||
-e "s|^GENARRATIVE_SPACETIME_SERVER_URL=.*|GENARRATIVE_SPACETIME_SERVER_URL=http://127.0.0.1:3101|" \
|
||||
deploy/env/api-server.env.example
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ pipeline {
|
||||
string(name: 'BUILD_NUMBER_TO_DEPLOY', defaultValue: '', description: '要复制归档产物的上游构建号')
|
||||
string(name: 'DATABASE', defaultValue: 'genarrative-prod', description: '生产 SpacetimeDB database')
|
||||
string(name: 'SPACETIME_SERVER', defaultValue: 'local', description: 'SpacetimeDB server alias')
|
||||
string(name: 'SPACETIME_SERVER_URL', defaultValue: 'http://127.0.0.1:3101', description: '显式 SpacetimeDB server URL,填写后优先于 SPACETIME_SERVER')
|
||||
booleanParam(name: 'CLEAR_DATABASE', defaultValue: false, description: '是否清空数据库后发布')
|
||||
}
|
||||
|
||||
@@ -47,6 +48,17 @@ pipeline {
|
||||
if (!params.DATABASE?.trim()) {
|
||||
error('DATABASE 不能为空。')
|
||||
}
|
||||
if (!params.SPACETIME_SERVER?.trim() && !params.SPACETIME_SERVER_URL?.trim()) {
|
||||
error('SPACETIME_SERVER 与 SPACETIME_SERVER_URL 不能同时为空。')
|
||||
}
|
||||
def spacetimeServerUrl = params.SPACETIME_SERVER_URL?.trim()
|
||||
if (spacetimeServerUrl && !(spacetimeServerUrl ==~ /^https?:\/\/[A-Za-z0-9._:-]+$/)) {
|
||||
error("SPACETIME_SERVER_URL 只能是 http(s) URL,且不能包含路径或 shell 特殊字符: ${spacetimeServerUrl}")
|
||||
}
|
||||
def spacetimeServer = params.SPACETIME_SERVER?.trim()
|
||||
if (!spacetimeServerUrl && spacetimeServer && !(spacetimeServer ==~ /^[A-Za-z0-9._:-]+$/)) {
|
||||
error("SPACETIME_SERVER 只能包含字母、数字、点、下划线、冒号和短横线: ${spacetimeServer}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,6 +111,9 @@ pipeline {
|
||||
steps {
|
||||
script {
|
||||
def clearArg = params.CLEAR_DATABASE ? '--clear-database' : ''
|
||||
def serverArg = params.SPACETIME_SERVER_URL?.trim()
|
||||
? "--server-url \"${params.SPACETIME_SERVER_URL.trim()}\""
|
||||
: "--server \"${params.SPACETIME_SERVER}\""
|
||||
sh """
|
||||
bash -lc '
|
||||
set -euo pipefail
|
||||
@@ -106,7 +121,7 @@ pipeline {
|
||||
scripts/deploy/production-stdb-publish.sh \\
|
||||
--source-dir "build/${params.BUILD_VERSION}" \\
|
||||
--database "${params.DATABASE}" \\
|
||||
--server "${params.SPACETIME_SERVER}" \\
|
||||
${serverArg} \\
|
||||
${clearArg}
|
||||
'
|
||||
"""
|
||||
|
||||
@@ -5,10 +5,11 @@ set -euo pipefail
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
用法:
|
||||
./scripts/deploy/production-stdb-publish.sh --source-dir build/<version> --database <database> [--server local] [--clear-database]
|
||||
./scripts/deploy/production-stdb-publish.sh --source-dir build/<version> --database <database> [--server-url http://127.0.0.1:3101] [--server local] [--clear-database]
|
||||
|
||||
说明:
|
||||
进入维护模式,校验 spacetime_module.wasm.sha256,并在生产实例本机执行 spacetime publish。
|
||||
默认使用 http://127.0.0.1:3101,避免与部署机本机 Git/Web 服务的 3000 端口冲突。
|
||||
失败时保留维护模式。
|
||||
EOF
|
||||
}
|
||||
@@ -36,6 +37,7 @@ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
SOURCE_DIR=""
|
||||
DATABASE=""
|
||||
SERVER_ALIAS="local"
|
||||
SERVER_URL="http://127.0.0.1:3101"
|
||||
CLEAR_DATABASE=0
|
||||
DEPLOY_COMPLETED=0
|
||||
|
||||
@@ -55,6 +57,11 @@ while [[ $# -gt 0 ]]; do
|
||||
;;
|
||||
--server)
|
||||
SERVER_ALIAS="${2:?缺少 --server 的值}"
|
||||
SERVER_URL=""
|
||||
shift 2
|
||||
;;
|
||||
--server-url)
|
||||
SERVER_URL="${2:?缺少 --server-url 的值}"
|
||||
shift 2
|
||||
;;
|
||||
--clear-database)
|
||||
@@ -106,16 +113,25 @@ echo "[production-stdb-publish] 校验 wasm"
|
||||
PUBLISH_ARGS=(
|
||||
publish
|
||||
"${DATABASE}"
|
||||
--server "${SERVER_ALIAS}"
|
||||
--bin-path "${SOURCE_DIR}/spacetime_module.wasm"
|
||||
--yes
|
||||
)
|
||||
|
||||
if [[ -n "${SERVER_URL}" ]]; then
|
||||
PUBLISH_ARGS+=(--server "${SERVER_URL}")
|
||||
else
|
||||
PUBLISH_ARGS+=(--server "${SERVER_ALIAS}")
|
||||
fi
|
||||
|
||||
if [[ "${CLEAR_DATABASE}" -eq 1 ]]; then
|
||||
PUBLISH_ARGS+=(--clear-database)
|
||||
fi
|
||||
|
||||
echo "[production-stdb-publish] 发布 SpacetimeDB module: ${DATABASE} -> ${SERVER_ALIAS}"
|
||||
if [[ -n "${SERVER_URL}" ]]; then
|
||||
echo "[production-stdb-publish] 发布 SpacetimeDB module: ${DATABASE} -> ${SERVER_URL}"
|
||||
else
|
||||
echo "[production-stdb-publish] 发布 SpacetimeDB module: ${DATABASE} -> ${SERVER_ALIAS}"
|
||||
fi
|
||||
spacetime "${PUBLISH_ARGS[@]}"
|
||||
|
||||
"${SCRIPT_DIR}/maintenance-off.sh"
|
||||
|
||||
Reference in New Issue
Block a user