Files
huangjingfen/docs/deploy.md
apple ae8b866319 feat(fsgx): 管理后台与部署相关更新
- admin: 路由守卫修复空白页、addRoute、devServer 端口与代理
- admin: package.json 生产构建去掉 NODE_OPTIONS openssl
- ajcaptcha: 滑块验证码改用 file 缓存避免 Redis NOAUTH
- nginx-crmeb: 增加 81 端口站点
- docs: deploy 补充 NOAUTH/Redis 说明,新增 H5 部署脚本与 nginx 示例
- 其他: database、start-api、swoole ini、uniapp 资源等

Made-with: Cursor
2026-03-21 02:33:14 +08:00

14 KiB
Raw Permalink Blame History

CRMEB Pro v3.5 简化发布部署方案

云端 .env、数据库、Nginx、Swoole 等已配置完成。本方案将服务器 API管理后台前端H5 前端拆分为三个子项目,可独立执行对应的发布部署。


一、部署信息

项目
服务器 root@182.92.142.158,密码 A@123456
部署根目录 /www/wwwroot/hjf.suzhouyuqi.com
域名 hjf.suzhouyuqi.com
本地项目路径 /Users/apple/scott2026/huangjingfen/pro_v3.5.1
子项目 本地路径 服务器目标路径
服务器 API pro_v3.5.1/(排除 view、public/admin /www/wwwroot/hjf.suzhouyuqi.com/
管理后台前端 pro_v3.5.1/view/admin/dist/ /www/wwwroot/hjf.suzhouyuqi.com/public/admin/
H5 前端 pro_v3.5.1/view/uniapp/unpackage/dist/build/web/.../h5/ /www/wwwroot/hjf.suzhouyuqi.com/public/

云服务器 Nginx 配置要求H5 根路径访问必备)

域名根路径 https://hjf.suzhouyuqi.com/ 需正确返回 H5 页面。若出现 Unexpected token '<'(请求 JS 时返回 HTML通常是 Nginx 未正确提供静态文件。

必须满足:

  1. 站点 root 指向 publicroot /www/wwwroot/hjf.suzhouyuqi.com/public;
  2. index 顺序index index.html index.php;(优先 index.html
  3. 静态文件优先:对 /static//assets//pages/ 等路径Nginx 应先尝试本地文件,仅当文件不存在时才转发到 PHP/Swoole。

推荐配置示例(宝塔/ LNMP 站点):

server {
    listen 80;
    listen 443 ssl http2;
    server_name hjf.suzhouyuqi.com;
    root /www/wwwroot/hjf.suzhouyuqi.com/public;
    index index.html index.php;

    # 静态资源:直接由 Nginx 提供,不转发到 PHP
    location ~ ^/(static|assets|pages)/ {
        try_files $uri =404;
        expires 7d;
    }

    # PHP 请求
    location ~ \.php$ {
        # 转发到 Swoole 或 php-fpm按现有配置
    }

    # 其余请求:先找静态文件,再走 PHP
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}

若使用 if (!-e $request_filename) { proxy_pass ... },需确保文件存在时不会进入 proxy,否则 /static/js/xxx.js 会被错误地返回 HTML。

完整示例见 docs/nginx-hjf-cloud.conf.example


二、子项目一:服务器 API

仅部署后端 PHP 代码app、crmeb、config、route、vendor、public 等),不覆盖管理后台和 H5 前端。

方式一:全量同步(先整站备份,再覆盖)

2.1.1 备份(服务器)

ssh root@182.92.142.158

mkdir -p /www/backup
tar -czvf /www/backup/hjf_api_$(date +%Y%m%d_%H%M%S).tar.gz \
  -C /www/wwwroot hjf.suzhouyuqi.com

2.1.2 上传(本地)

cd /Users/apple/scott2026/huangjingfen

rsync -avz --delete \
  --exclude='.env' \
  --exclude='.git' \
  --exclude='node_modules' \
  --exclude='view' \
  --exclude='public/admin' \
  --exclude='public/uploads' \
  --exclude='runtime/cache' \
  --exclude='runtime/log' \
  --exclude='.cursor' \
  --exclude='.cursor-cli' \
  pro_v3.5.1/ \
  root@182.92.142.158:/www/wwwroot/hjf.suzhouyuqi.com/

方式二:按 Git 版本增量部署(仅上传 git 中有变更的文件)

对比 origin/main 与本地工作区,先列出将要上传的文件,再通过 SSH 执行「先备份再上传覆盖」。

2.2.1 步骤一:列出将要上传的文件

cd /Users/apple/scott2026/huangjingfen

git fetch origin
git diff --name-only origin/main -- pro_v3.5.1/ \
  | sed 's|^pro_v3.5.1/||' \
  | grep -v '^view' \
  | grep -v '^public/admin' \
  | grep -v '^public/uploads' \
  | grep -v '^runtime/cache' \
  | grep -v '^runtime/log' \
  | grep -v '\.env$' \
  | grep -v '/\.' \
  | tee /tmp/hjf_api_changed.txt

确认列表无误后,执行步骤二。

2.2.2 步骤二:通过 SSH 发布部署

cd /Users/apple/scott2026/huangjingfen

# 若无变更则退出
if [ ! -s /tmp/hjf_api_changed.txt ]; then
  echo "无 API 相关文件变更,跳过部署"
  exit 0
fi

# 创建备份目录SSH 执行)
BACKUP_SUFFIX=$(date +%Y%m%d_%H%M%S)
ssh root@182.92.142.158 "mkdir -p /www/backup/hjf_api_git_${BACKUP_SUFFIX}"

# 通过 rsync over SSH 上传变更文件(覆盖前自动备份到 backup-dir
rsync -avz --backup --backup-dir=/www/backup/hjf_api_git_${BACKUP_SUFFIX} \
  --files-from=/tmp/hjf_api_changed.txt \
  pro_v3.5.1/ \
  root@182.92.142.158:/www/wwwroot/hjf.suzhouyuqi.com/

说明:

  • 步骤一用 tee 同时输出到屏幕和 /tmp/hjf_api_changed.txt,步骤二复用该文件。
  • origin/main 为基准;可改为 origin/其他分支标签名
  • --backup --backup-dir=...:覆盖前将服务器上的旧文件移动到备份目录。
  • 增量备份目录示例:/www/backup/hjf_api_git_20260117_143022/

2.3 上传后(服务器)

ssh root@182.92.142.158

supervisorctl restart hjfshop-swoole
cd /www/wwwroot/hjf.suzhouyuqi.com && php think clear

三、子项目二:管理后台前端

仅部署管理后台 Vue 构建产物到 public/admin/

3.1 本地构建

cd /Users/apple/scott2026/huangjingfen/pro_v3.5.1/view/admin

npm install   # 依赖有变更时执行
npm run build

构建产物在 view/admin/dist/

3.2 备份(服务器)

ssh root@182.92.142.158

mkdir -p /www/backup
tar -czvf /www/backup/hjf_admin_$(date +%Y%m%d_%H%M%S).tar.gz \
  -C /www/wwwroot/hjf.suzhouyuqi.com/public admin

3.3 上传(本地)

方式 Arsync(服务器需已安装 rsync

cd /Users/apple/scott2026/huangjingfen

rsync -avz --delete \
  pro_v3.5.1/view/admin/dist/ \
  root@182.92.142.158:/www/wwwroot/hjf.suzhouyuqi.com/public/admin/

方式 Btar + ssh(服务器无 rsync 时使用)

cd /Users/apple/scott2026/huangjingfen

tar czf - -C pro_v3.5.1/view/admin/dist . | \
  ssh root@182.92.142.158 "cd /www/wwwroot/hjf.suzhouyuqi.com/public && rm -rf admin && mkdir -p admin && tar xzf - -C admin"

3.4 上传后修改权限(服务器)

ssh root@182.92.142.158

chown -R www:www /www/wwwroot/hjf.suzhouyuqi.com/public/admin
chmod -R 775 /www/wwwroot/hjf.suzhouyuqi.com/public/admin

3.5 验证

浏览器访问 http://hjf.suzhouyuqi.com/admin/login,确认页面正常。

3.6 本地环境部署

将管理后台前端打包并部署到本机,配合 nginx-crmeb.conf 与 Swoole 使用。

前置条件:

  • Nginx 已加载 pro_v3.5.1/nginx-crmeb.confroot 指向 pro_v3.5.1/public80 反代到 20199
  • Swoole API 已启动:./help/start-api.shphp -d memory_limit=300M think swoole

步骤:

# 1. 本地构建(同 3.1
cd /Users/apple/scott2026/huangjingfen/pro_v3.5.1/view/admin
npm install   # 依赖有变更时执行
npm run build

# 2. 将构建产物复制到 public/admin覆盖旧文件
cd /Users/apple/scott2026/huangjingfen
rm -rf pro_v3.5.1/public/admin
cp -r pro_v3.5.1/view/admin/dist pro_v3.5.1/public/admin

或使用 rsync保留权限、便于增量更新

cd /Users/apple/scott2026/huangjingfen
rsync -av --delete pro_v3.5.1/view/admin/dist/ pro_v3.5.1/public/admin/

验证:

浏览器访问 http://127.0.0.1/admin/http://127.0.0.1/admin/login,确认管理后台页面正常。


四、子项目三H5 前端

仅部署 H5 构建产物到 public/(站点根目录)。部署时仅覆盖 H5 相关文件,不删除 admin/index.php 等。

4.1 本地打包HBuilder 或 npm

方式 AHBuilder 打包(推荐)

  1. 用 HBuilderX 打开 pro_v3.5.1/view/uniapp 项目
  2. 确认 config/app.jsBASE_HOST 已设为云服务器域名(如 hjf.suzhouyuqi.com
  3. 菜单:发行 → 网站-H5 手机版(或 Web → 填写网站标题 → 发行
  4. 构建产物在 view/uniapp/unpackage/dist/build/web/.../build/h5/

方式 B命令行构建

cd /Users/apple/scott2026/huangjingfen/pro_v3.5.1/view/uniapp

npm install   # 依赖有变更时执行
npm run build:h5

构建产物在 view/uniapp/unpackage/dist/build/h5/

4.2 备份(服务器,上传前执行)

上传前在服务器备份 public 目录,便于回滚:

ssh root@182.92.142.158

mkdir -p /www/wwwroot/backup
tar -czvf /www/wwwroot/backup/hjf_public_$(date +%Y%m%d_%H%M%S).tar.gz \
  -C /www/wwwroot/hjf.suzhouyuqi.com public

一键部署脚本 deploy-h5.sh 会自动执行此备份后再上传。

4.3 上传(本地)

方式 Arsync(服务器需已安装 rsync

cd /Users/apple/scott2026/huangjingfen

rsync -avz \
  pro_v3.5.1/view/uniapp/unpackage/dist/build/h5/ \
  root@182.92.142.158:/www/wwwroot/hjf.suzhouyuqi.com/public/

不使用 --delete,避免覆盖或删除 admin/index.php 等文件。

方式 Btar + ssh(服务器无 rsync 时使用)

cd /Users/apple/scott2026/huangjingfen

tar czf - -C pro_v3.5.1/view/uniapp/unpackage/dist/build/h5 . | \
  ssh root@182.92.142.158 "cd /www/wwwroot/hjf.suzhouyuqi.com/public && tar xzf -"

仅解压覆盖 H5 文件index.html、static/ 等),不删除 admin/

方式 Cscp

cd /Users/apple/scott2026/huangjingfen

scp -r pro_v3.5.1/view/uniapp/unpackage/dist/build/h5/* \
  root@182.92.142.158:/www/wwwroot/hjf.suzhouyuqi.com/public/

4.4 上传后修改权限(服务器)

ssh root@182.92.142.158

chown -R www:www /www/wwwroot/hjf.suzhouyuqi.com/public
chmod -R 755 /www/wwwroot/hjf.suzhouyuqi.com/public

若仅更新 H5 根目录下的 index.html、static 等,可只对相关路径执行:
chown -R www:www /www/wwwroot/hjf.suzhouyuqi.com/public/index.html /www/wwwroot/hjf.suzhouyuqi.com/public/static

4.5 一键部署脚本(本地执行)

脚本 docs/deploy-h5.sh 会依次执行:备份上一版本 → 上传 → 修改权限。执行前确保已打包好 H5unpackage/dist/build/web/h5/ 存在):

#!/usr/bin/env bash
# H5 前端一键部署到云服务器(需 sshpass或已配置 SSH 免密)
# 支持 HBuilder 导出 web 或 h5 路径
set -e
cd "$(dirname "$0")/.."
REMOTE="root@182.92.142.158"
REMOTE_PUBLIC="/www/wwwroot/hjf.suzhouyuqi.com/public"
BACKUP_DIR="/www/wwwroot/backup"

# 优先使用 web其次 h5
if [ -d "pro_v3.5.1/view/uniapp/unpackage/dist/build/web" ]; then
  H5_SRC="pro_v3.5.1/view/uniapp/unpackage/dist/build/web"
elif [ -d "pro_v3.5.1/view/uniapp/unpackage/dist/build/h5" ]; then
  H5_SRC="pro_v3.5.1/view/uniapp/unpackage/dist/build/h5"
else
  echo "错误:未找到 H5 构建产物,请先用 HBuilder 或 npm run build:h5 打包"
  exit 1
fi

echo "备份云服务器 public 目录(上一版本)..."
ssh "$REMOTE" "mkdir -p $BACKUP_DIR && tar -czf $BACKUP_DIR/hjf_public_\$(date +%Y%m%d_%H%M%S).tar.gz -C /www/wwwroot/hjf.suzhouyuqi.com public && echo '备份完成'"

echo "上传 H5 到 $REMOTE:$REMOTE_PUBLIC ..."
tar czf - -C "$H5_SRC" . | ssh "$REMOTE" "cd $REMOTE_PUBLIC && tar xzf -"

echo "修改权限 ..."
ssh "$REMOTE" "chown -R www:www $REMOTE_PUBLIC && chmod -R 755 $REMOTE_PUBLIC"

echo "部署完成,请访问 https://hjf.suzhouyuqi.com/ 验证"

用法:

cd /Users/apple/scott2026/huangjingfen
chmod +x docs/deploy-h5.sh
./docs/deploy-h5.sh

若需密码,可安装 sshpass 后使用:SSHPASS='A@123456' sshpass -e ./docs/deploy-h5.sh

4.6 验证

浏览器访问 http://hjf.suzhouyuqi.com/https://hjf.suzhouyuqi.com/,确认 H5 页面正常。

4.7 H5 报错 Unexpected token '<' 排查

现象:访问根路径时控制台报 index.xxx.js:1 Uncaught SyntaxError: Unexpected token '<'

原因:请求 JS 时服务器返回了 HTML404 页或 index.php 输出)。常见情况:

  • index.html 引用 /h5/static/...:旧版 index 与当前部署路径不一致,/h5/static/js/xxx.js 返回 404 → HTML
  • Nginx 未正确提供静态文件root 未指向 .../public 或缺少 location ~ ^/(static|assets|pages)/

排查步骤

  1. 检查 index.html 引用路径
    curl -s "https://hjf.suzhouyuqi.com/" | grep -oE 'src=[^>]+\.js'
    
    若出现 /h5/static/,说明服务器 index.html 为旧版,需重新部署。
  2. 重新构建并部署(部署脚本会先清理旧 index.html、static 等):
    # 本地HBuilder 发行 H5 或 npm run build:h5
    ./docs/deploy-h5.sh
    
  3. 确认 Nginx root:站点 root 必须为 .../public,见上文「云服务器 Nginx 配置要求」。
  4. 清除浏览器缓存强制刷新Ctrl+Shift+R或无痕模式访问。

四(补充)、管理后台登录滑块:NOAUTH Authentication required

若访问 /adminapi/ajcaptcha/adminapi/is_captcha 返回 {"msg":"NOAUTH Authentication required."},说明 Redis 需要密码但 .env[REDIS]PASSWORD 与服务器 Redis 不一致(或 Redis 开启了 requirepass.env 为空)。

处理:

  1. 在服务器上核对 Redisredis-cli -h <主机> -p 6379 -a '<实际密码>' ping,将正确密码写入站点根目录 .envPASSWORD = ...
  2. 重启 Swoole / PHP 进程使配置生效。
  3. 项目已把 滑块验证码ajcaptcha缓存改为本地 file,不依赖 Redis 认证;部署后请同步更新 config/ajcaptcha.php。登录次数统计等仍走 Redis长期仍须修正 Redis 配置

五、发布检查汇总

子项目 检查项
API supervisorctl status hjfshop-swoole 为 RUNNINGcurl http://hjf.suzhouyuqi.com/adminapi/login/info 返回 JSON
管理后台 http://hjf.suzhouyuqi.com/admin/login 可打开;登录后无「暂未授权」提示
H5 http://hjf.suzhouyuqi.com/ 可打开

六、回滚

按备份文件名中的时间戳选择对应子项目备份恢复:

ssh root@182.92.142.158

# 回滚 API整站
cd /www/wwwroot
rm -rf hjf.suzhouyuqi.com
tar -xzvf /www/backup/hjf_api_YYYYMMDD_HHMMSS.tar.gz
supervisorctl restart hjfshop-swoole

# 回滚管理后台(仅 public/admin
rm -rf /www/wwwroot/hjf.suzhouyuqi.com/public/admin
tar -xzvf /www/backup/hjf_admin_YYYYMMDD_HHMMSS.tar.gz -C /www/wwwroot/hjf.suzhouyuqi.com/public

# 回滚 H5恢复 public/ 目录)
rm -rf /www/wwwroot/hjf.suzhouyuqi.com/public
tar -xzvf /www/wwwroot/backup/hjf_public_YYYYMMDD_HHMMSS.tar.gz -C /www/wwwroot/hjf.suzhouyuqi.com