fix(deploy): production CRM deployment improvements

- Fix deploy_crm_only.sh: non-destructive hot reload
  - Enhanced stop logic with pgrep + fuser for port release
  - Added 3-layer verification (process/control/user)
  - Check /proc/$pid/exe for (deleted) marker
  - Never delete DB

- Fix portal script contracts: crm_session → crm_subject
  - deploy_tksea_portal.sh: use $cookie_crm_subject
  - test_tksea_portal_assets.sh: assert crm_subject exists
  - nginx.example.conf: updated trusted subject header

- Add systemd service management
  - sub2api-crm.service.template
  - install_crm_systemd.sh
  - verify_crm_deployment.sh

Update docs/plans/2026-06-04-next-version-plan.md with deployment findings.
This commit is contained in:
phamnazage-jpg
2026-06-10 15:44:45 +08:00
parent 85954e516a
commit 47ced19c7b
10 changed files with 915 additions and 60 deletions

View File

@@ -14,6 +14,9 @@ ADMIN_PROVIDERS_FILE="$ROOT_DIR/deploy/tksea-portal/admin/providers.html"
ADMIN_BATCH_FILE="$ROOT_DIR/deploy/tksea-portal/admin/batch-import.html"
NGINX_FILE="$ROOT_DIR/deploy/tksea-portal/nginx.sub.tksea.top.conf.example"
DEPLOY_SCRIPT="$ROOT_DIR/scripts/deploy/deploy_tksea_portal.sh"
DEPLOY_ENV_EXAMPLE="$ROOT_DIR/scripts/deploy/.env.deploy.example"
DEPLOY_CRM_ONLY_SCRIPT="$ROOT_DIR/scripts/deploy/deploy_crm_only.sh"
REMOTE43_SETUP_SCRIPT="$ROOT_DIR/scripts/deploy/setup_remote43_patched_stack.sh"
fail() {
echo "FAIL: $*" >&2
@@ -28,6 +31,14 @@ assert_contains_file() {
fi
}
assert_not_contains_file() {
local file="$1"
local needle="$2"
if grep -Fq "$needle" "$file"; then
fail "did not expect [$needle] in $file"
fi
}
[[ -f "$HTML_FILE" ]] || fail "missing $HTML_FILE"
[[ -f "$ADMIN_HTML_FILE" ]] || fail "missing $ADMIN_HTML_FILE"
[[ -f "$ADMIN_COMMON_CSS_FILE" ]] || fail "missing $ADMIN_COMMON_CSS_FILE"
@@ -40,6 +51,9 @@ assert_contains_file() {
[[ -f "$ADMIN_BATCH_FILE" ]] || fail "missing $ADMIN_BATCH_FILE"
[[ -f "$NGINX_FILE" ]] || fail "missing $NGINX_FILE"
[[ -f "$DEPLOY_SCRIPT" ]] || fail "missing $DEPLOY_SCRIPT"
[[ -f "$DEPLOY_ENV_EXAMPLE" ]] || fail "missing $DEPLOY_ENV_EXAMPLE"
[[ -f "$DEPLOY_CRM_ONLY_SCRIPT" ]] || fail "missing $DEPLOY_CRM_ONLY_SCRIPT"
[[ -f "$REMOTE43_SETUP_SCRIPT" ]] || fail "missing $REMOTE43_SETUP_SCRIPT"
assert_contains_file "$HTML_FILE" "Sub2API 多模型接入中心"
assert_contains_file "$HTML_FILE" "https://sub.tksea.top/portal/"
@@ -111,7 +125,24 @@ assert_contains_file "$ADMIN_COMMON_JS_FILE" "/portal/admin/route-health.html"
assert_contains_file "$ADMIN_COMMON_JS_FILE" "/portal/admin/accounts.html"
assert_contains_file "$ADMIN_COMMON_JS_FILE" "/portal/admin/providers.html"
assert_contains_file "$ADMIN_COMMON_JS_FILE" "/portal/admin/batch-import.html"
# 契约修正crm_subject 是 trusted subject 来源crm_session 已弃用
assert_contains_file "$NGINX_FILE" '$cookie_crm_subject'
assert_not_contains_file "$NGINX_FILE" '$cookie_crm_session'
assert_contains_file "$DEPLOY_SCRIPT" '$cookie_crm_subject'
assert_not_contains_file "$DEPLOY_SCRIPT" '$cookie_crm_session'
assert_contains_file "$ADMIN_COMMON_JS_FILE" "/portal/"
assert_contains_file "$ADMIN_COMMON_JS_FILE" "filterSensitiveData"
assert_contains_file "$ADMIN_COMMON_JS_FILE" "containsSensitiveData(payload)"
assert_not_contains_file "$ADMIN_ACCOUNTS_FILE" "adminToken: adminTokenInput.value,"
assert_not_contains_file "$ADMIN_PROVIDERS_FILE" "adminToken: adminTokenInput.value,"
assert_not_contains_file "$ADMIN_PROVIDERS_FILE" "accessAPIKey: accessAPIKeyInput.value.trim(),"
assert_not_contains_file "$ADMIN_PROVIDERS_FILE" "providerKeys: providerKeysInput.value,"
assert_not_contains_file "$ADMIN_HTML_FILE" "adminToken: adminTokenInput.value,"
assert_not_contains_file "$ADMIN_HTML_FILE" "probeAPIKey: probeAPIKeyInput.value.trim(),"
assert_not_contains_file "$ADMIN_HTML_FILE" "entries: entriesInput.value,"
assert_not_contains_file "$ADMIN_ROUTE_HEALTH_FILE" "localStorage.setItem(storageKey"
assert_not_contains_file "$ADMIN_LOGICAL_GROUPS_FILE" "localStorage.setItem(storageKey"
assert_contains_file "$ADMIN_HTML_FILE" "Batch Import Admin"
assert_contains_file "$ADMIN_HTML_FILE" "/portal/admin-common.css"
@@ -190,6 +221,12 @@ assert_contains_file "$ADMIN_ACCOUNTS_FILE" "/portal-admin-api"
assert_contains_file "$ADMIN_PROVIDERS_FILE" "Provider Admin"
assert_contains_file "$ADMIN_PROVIDERS_FILE" "/portal/admin-common.css"
assert_contains_file "$ADMIN_PROVIDERS_FILE" "/portal/admin-common.js"
assert_not_contains_file "$DEPLOY_CRM_ONLY_SCRIPT" 'KEY="${KEY:-/home/long/下载/zjsea.pem}"'
assert_not_contains_file "$DEPLOY_CRM_ONLY_SCRIPT" 'REMOTE="${REMOTE:-ubuntu@43.155.133.187}"'
assert_not_contains_file "$REMOTE43_SETUP_SCRIPT" 'KEY="${KEY:-/home/long/下载/zjsea.pem}"'
assert_not_contains_file "$REMOTE43_SETUP_SCRIPT" 'REMOTE="${REMOTE:-ubuntu@43.155.133.187}"'
assert_contains_file "$DEPLOY_CRM_ONLY_SCRIPT" '.env.deploy.example'
assert_contains_file "$REMOTE43_SETUP_SCRIPT" '.env.deploy.example'
assert_contains_file "$ADMIN_PROVIDERS_FILE" "data-admin-nav"
assert_contains_file "$ADMIN_PROVIDERS_FILE" "管理员登录"
assert_contains_file "$ADMIN_PROVIDERS_FILE" "/api/packs"
@@ -237,5 +274,12 @@ assert_contains_file "$DEPLOY_SCRIPT" "REMOTE_PORTAL_DIR"
assert_contains_file "$DEPLOY_SCRIPT" "REMOTE_CRM_PORT"
assert_contains_file "$DEPLOY_SCRIPT" "LOCAL_PORTAL_DIR"
assert_contains_file "$DEPLOY_SCRIPT" "patch_tksea_portal_nginx.py"
assert_contains_file "$DEPLOY_SCRIPT" "DEPLOY_ENV_FILE"
assert_not_contains_file "$DEPLOY_SCRIPT" "/home/long/下载/zjsea.pem"
assert_not_contains_file "$DEPLOY_SCRIPT" "ubuntu@43.155.133.187"
assert_contains_file "$DEPLOY_ENV_EXAMPLE" "KEY="
assert_contains_file "$DEPLOY_ENV_EXAMPLE" "REMOTE="
assert_contains_file "$DEPLOY_ENV_EXAMPLE" "REMOTE_CRM_PORT="
echo "PASS: tksea portal assets look consistent"