H5转APP打包系统 — 宝塔面板部署教程(超详细版)

H5转APP打包系统

宝塔面板部署教程(超详细版)— 零基础也能轻松部署

🛠️ 技术栈介绍

前端技术栈

技术版本说明
Vue.js3.x前端框架,负责页面渲染和交互
Vite5.x前端构建工具,用于编译打包前端代码
Element Plus2.xUI 组件库,提供按钮、表格、表单等界面组件
Vue Router4.x前端路由,管理页面跳转
Axios1.xHTTP 请求库,用于调用后端 API

后端技术栈

技术版本说明
Node.js16.xJavaScript 运行环境,后端程序运行的基础
Express4.xWeb 框架,处理 HTTP 请求和路由
MySQL5.7 / 8.0关系型数据库,存储用户、项目、构建记录等数据
mysql23.xMySQL 驱动,用于 Node.js 连接 MySQL 数据库
JWT (jsonwebtoken)9.x用户身份认证,生成和验证登录 Token
Multer1.x文件上传中间件,处理图标、启动页等文件上传
Sharp0.33.x图片处理库,自动裁剪适配不同分辨率的图标
JSZip3.xZIP 文件处理,用于 Android APK 资源合并
Nitron1.2.xAndroid APK 打包工具,生成可安装的 APK 文件
apktool2.xAndroid APK 反编译/重打包工具(需要 Java 环境)
uber-apk-signer1.xAPK 签名工具,对打包后的 APK 进行正式签名
ldid-iOS 应用签名工具(IPA 打包需要)

运维工具

工具说明
宝塔面板 (BT Panel)可视化服务器管理面板,简化部署操作
NginxWeb 服务器,做反向代理和静态文件服务
PM2Node.js 进程管理器,保证服务持续运行、崩溃自动重启、开机自启
Java 8 (OpenJDK)Android APK 打包工具 apktool 的运行依赖

项目架构图

用户浏览器
    │
    ▼
┌─────────────┐
│   Nginx     │ ← 80/443 端口,处理静态文件和反向代理
│  (反向代理)  │
└──────┬──────┘
       │
       ├──── 静态文件 ──── /www/wwwroot/h5-to-app/web/dist/ (Vue 前端)
       │
       └──── /api/* ────── Node.js (Express) 后端 :3000
                              │
                              ├── MySQL 数据库 :3306
                              ├── 文件上传 (uploads/)
                              ├── APK 打包 (builds/)
                              │    ├── apktool (需要 Java)
                              │    ├── uber-apk-signer
                              │    └── nitron
                              └── IPA 打包 (builds/)
                                   └── ldid (iOS 签名)

一、服务器要求

在开始之前,你需要一台云服务器。以下是最低配置要求:

项目最低要求推荐配置
操作系统CentOS 7.x / Ubuntu 20.04 / Debian 10CentOS 7.9 / Ubuntu 20.04
CPU1 核2 核及以上
内存1 GB2 GB 及以上(打包APK需要内存)
硬盘20 GB40 GB 及以上(存放构建产物)
带宽1 Mbps5 Mbps 及以上
网络需要公网IP独立公网IP

软件要求

  • Node.js 16.x 或更高版本
  • MySQL 5.7+ 或 8.0(推荐 5.7,兼容性最好)
  • Nginx(宝塔自带)
  • PM2(Node.js 进程管理工具)
  • Java 8+(用于 Android APK 打包,apktool 需要)
国内推荐购买阿里云、腾讯云、华为云的服务器。新用户有优惠,一般一年几十到一百多元即可。选择 CentOS 7.9 或 Ubuntu 20.04 系统镜像。

二、购买并连接服务器

2.1 购买服务器

  1. 前往 阿里云 / 腾讯云 / 华为云
  2. 注册账号并完成实名认证
  3. 选择「云服务器 ECS」或「轻量应用服务器」
  4. 选择配置:地域选最近的,操作系统选 CentOS 7.9 64位,规格最低 1核1G,推荐 2核4G
  5. 设置 root 密码(务必记好,后面要用
  6. 购买完成后,在控制台找到你的服务器公网IP地址

2.2 连接服务器

方式一:使用 XShell / PuTTY

  1. 下载 XShell(个人版免费)或 PuTTY
  2. 新建连接:主机填写服务器公网IP,端口 22,用户名 root,密码是你购买时设置的密码

方式二:使用云服务商的网页终端

  1. 登录云服务商控制台
  2. 找到你的服务器实例
  3. 点击「远程连接」或「VNC连接」
连接成功后你会看到类似 [root@iZxxx ~]# 这样的命令提示符,表示已经成功登录服务器。

三、安装宝塔面板

3.1 什么是宝塔面板?

宝塔面板是一个可视化的服务器管理工具,让你通过网页界面来管理服务器,不需要记大量命令。就像给服务器装了一个「桌面操作系统」。

3.2 安装宝塔面板

连接到服务器终端后,根据你的操作系统执行对应的安装命令:

CentOS 系统:

yum install -y wget && wget -O install.sh https://download.bt.cn/install/install_6.0.sh && sh install.sh

Ubuntu / Debian 系统:

wget -O install.sh https://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh

3.3 安装过程

  1. 执行命令后,系统会询问你是否安装到 /www 目录,输入 y 然后回车
  2. 等待安装(大约 2-5 分钟)
  3. 安装完成后,屏幕上会显示以下重要信息,请务必复制保存:
==========================================
Bt-Panel: http://你的服务器IP:8888/abcdef123
username: abcdef
password: ghijklmnop
==========================================

Bt-Panel 后面的网址就是你的宝塔面板登录地址
username 是登录用户名
password 是登录密码
请务必截图或复制保存这些信息!

3.4 登录宝塔面板

  1. 在浏览器中打开上面显示的地址
  2. 输入用户名和密码登录
  3. 首次登录可能会弹出「推荐安装套件」,先点击取消,我们手动安装需要的软件

3.5 安全组/防火墙放行端口

这一步非常重要,否则你将无法访问面板和网站!

如果你使用的是阿里云/腾讯云/华为云,进入云服务器控制台 → 找到「安全组」或「防火墙」→ 添加以下端口的入站规则:

端口协议用途
8888TCP宝塔面板
80TCPHTTP 网站访问
443TCPHTTPS 网站访问
3000TCPNode.js 后端(调试用)
22TCPSSH 连接

如果服务器本身有防火墙,执行以下命令:

# CentOS 7 使用 firewalld
firewall-cmd --permanent --add-port=8888/tcp
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --permanent --add-port=22/tcp
firewall-cmd --reload

# Ubuntu 使用 ufw
ufw allow 8888
ufw allow 80
ufw allow 443
ufw allow 22
ufw reload

四、安装基础软件环境

登录宝塔面板后,我们需要安装 Nginx 和 MySQL。

4.1 安装 Nginx

  1. 在宝塔面板左侧菜单点击 「软件商店」
  2. 搜索 「Nginx」
  3. 点击 「安装」,选择推荐版本(如 1.24 或 1.22)
  4. 点击 「确定」,等待安装完成(约 2-3 分钟)

4.2 安装 MySQL

  1. 在软件商店搜索 「MySQL」
  2. 点击 「安装」,选择版本 MySQL 5.7(推荐,兼容性好)
  3. 点击 「确定」,等待安装完成(约 3-5 分钟)

4.3 安装 Java(用于 Android 打包)

Android 打包工具 apktool 需要 Java 环境。

# CentOS
yum install -y java-1.8.0-openjdk

# Ubuntu / Debian
apt-get install -y openjdk-8-jdk

验证安装是否成功:

java -version
# 应该显示类似 openjdk version "1.8.0_xxx" 的输出

4.4 安装必要编译工具

# CentOS
yum install -y gcc gcc-c++ make automake autoconf libtool

# Ubuntu / Debian
apt-get install -y build-essential

五、安装 Node.js 和 PM2

5.1 方式一:通过宝塔面板安装(推荐新手)

  1. 在宝塔面板 「软件商店」 搜索 「Node.js版本管理器」
  2. 点击 「安装」
  3. 安装完成后,点击 「设置」
  4. 在版本管理器中,选择安装 Node.js 16.x(如 16.20.2)
  5. 点击 「安装」,等待完成

5.2 方式二:通过命令行安装 nvm 和 Node.js

# 安装 nvm(Node.js 版本管理器)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# 加载 nvm 到当前环境
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

# 安装 Node.js 16
nvm install 16

# 设置默认使用 Node.js 16
nvm use 16
nvm alias default 16

5.3 验证 Node.js 安装

node -v
# 应该显示:v16.x.x

npm -v
# 应该显示:8.x.x 或更高

5.4 设置 npm 国内镜像(强烈推荐)

npm config set registry https://registry.npmmirror.com

# 验证
npm config get registry
# 应该显示:https://registry.npmmirror.com

5.5 安装 PM2

npm install -g pm2

# 验证安装
pm2 -v

六、创建 MySQL 数据库

6.1 在宝塔面板中创建数据库

  1. 在宝塔面板左侧菜单点击 「数据库」
  2. 点击 「添加数据库」 按钮
  3. 填写以下信息:
字段填写内容
数据库名h5app(或你喜欢的名字)
用户名h5app(或你喜欢的名字)
密码点击「随机」生成一个密码,务必复制保存
访问权限选择「本地服务器」(localhost)

6.2 记下数据库信息

数据库名:h5app
用户名:h5app
密码:xxxxxxxx(你刚才生成的密码)
主机:localhost
端口:3306

6.3 导入数据库表结构

数据库创建后是空的,我们需要导入表结构。

方式一:通过宝塔面板的 phpMyAdmin 导入(推荐新手)

  1. 在宝塔面板 「数据库」 页面,找到你刚创建的数据库
  2. 点击右侧的 「管理」 按钮,会打开 phpMyAdmin
  3. 在 phpMyAdmin 中,点击顶部的 「SQL」 标签
  4. 将以下 SQL 代码粘贴进去,点击 「执行」
USE h5app;

CREATE TABLE IF NOT EXISTS users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(100) NOT NULL UNIQUE,
  password VARCHAR(255) NOT NULL,
  email VARCHAR(255),
  role VARCHAR(20) DEFAULT 'user',
  build_credits INT DEFAULT 0,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  INDEX idx_username (username)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS projects (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  name VARCHAR(255) NOT NULL,
  url TEXT,
  package_name VARCHAR(255),
  version_name VARCHAR(50) DEFAULT '1.0.0',
  version_code INT DEFAULT 1,
  icon_path VARCHAR(500),
  splash_path VARCHAR(500),
  orientation VARCHAR(20) DEFAULT 'portrait',
  status_bar_style VARCHAR(20) DEFAULT 'default',
  status_bar_color VARCHAR(20) DEFAULT '#ffffff',
  fullscreen TINYINT(1) DEFAULT 0,
  android_enabled TINYINT(1) DEFAULT 1,
  ios_enabled TINYINT(1) DEFAULT 1,
  ios_cert_id INT,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  INDEX idx_user_id (user_id),
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS builds (
  id INT AUTO_INCREMENT PRIMARY KEY,
  project_id INT NOT NULL,
  build_number INT DEFAULT 0,
  platform VARCHAR(20) NOT NULL,
  status VARCHAR(20) DEFAULT 'pending',
  version VARCHAR(50),
  apk_path VARCHAR(500),
  ipa_path VARCHAR(500),
  manifest_path VARCHAR(500),
  mobileconfig_path VARCHAR(500),
  download_page VARCHAR(500),
  build_log TEXT,
  error_message TEXT,
  completed_at DATETIME,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_project_id (project_id),
  INDEX idx_status (status),
  FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS certificates (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  name VARCHAR(255),
  platform VARCHAR(20),
  cert_path VARCHAR(500),
  key_path VARCHAR(500),
  profile_path VARCHAR(500),
  password VARCHAR(255),
  is_active TINYINT(1) DEFAULT 1,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_user_id (user_id),
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS download_pages (
  id INT AUTO_INCREMENT PRIMARY KEY,
  build_id INT NOT NULL UNIQUE,
  project_id INT NOT NULL,
  title VARCHAR(255),
  description TEXT,
  icon_path VARCHAR(500),
  download_count INT DEFAULT 0,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_build_id (build_id),
  FOREIGN KEY (build_id) REFERENCES builds(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS orders (
  id INT AUTO_INCREMENT PRIMARY KEY,
  user_id INT NOT NULL,
  project_id INT,
  build_id INT,
  out_trade_no VARCHAR(100) NOT NULL UNIQUE,
  trade_no VARCHAR(100),
  name VARCHAR(255),
  amount DECIMAL(10,2) NOT NULL,
  paid_amount DECIMAL(10,2),
  status VARCHAR(20) DEFAULT 'pending',
  pay_type VARCHAR(20),
  platform VARCHAR(20),
  order_type VARCHAR(20),
  frontend_origin VARCHAR(500),
  paid_at DATETIME,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  INDEX idx_user_id (user_id),
  INDEX idx_out_trade_no (out_trade_no),
  INDEX idx_status (status),
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS settings (
  id INT AUTO_INCREMENT PRIMARY KEY,
  setting_key VARCHAR(100) NOT NULL UNIQUE,
  setting_value TEXT,
  INDEX idx_key (setting_key)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO settings (setting_key, setting_value) VALUES
  ('site_title', '"H5转APP打包系统"'),
  ('site_description', '"在线将H5网页打包成Android APK和iOS IPA应用"'),
  ('site_keywords', '"H5转APP,网页打包,APK打包,IPA打包,在线打包"'),
  ('site_footer', '"© 2026 H5转APP打包系统"'),
  ('contact_email', '""'),
  ('icp_number', '""'),
  ('domain', '""')
ON DUPLICATE KEY UPDATE setting_value = setting_value;
如果你的数据库名不是 h5app,请把第一行 USE h5app; 改成你的数据库名。

七、上传项目文件

7.1 准备部署包

确保你已经有了完整的项目文件包,包含以下目录结构:

h5-to-app/
├── server/          ← 后端代码
│   ├── src/         ← 源代码
│   ├── tools/       ← 工具(apktool.jar 等)
│   ├── .env.example ← 环境变量模板
│   ├── ecosystem.config.js
│   ├── package.json
│   └── nitron-release.keystore
├── web/
│   └── dist/        ← 前端编译产物(已构建好)
│       ├── assets/
│       ├── index.html
│       └── ...
└── deploy/
    ├── nginx.conf   ← Nginx 配置文件
    └── deploy.sh    ← 一键部署脚本

7.2 通过宝塔文件管理器上传

  1. 在宝塔面板左侧菜单点击 「文件」
  2. 在左侧目录树中,进入 /www/wwwroot/ 目录
  3. 点击顶部的 「上传」 按钮
  4. 将你的项目压缩包(如 h5-to-app.zip)上传到 /www/wwwroot/
  5. 上传完成后,右键点击压缩包 → 「解压」
  6. 解压目标路径设为 /www/wwwroot/h5-to-app
  7. 点击 「确定」

7.3 通过命令行上传(适合大文件)

# 在你的本地电脑上使用 scp 命令上传
scp h5-to-app.zip root@你的服务器IP:/www/wwwroot/

# 在服务器上解压
cd /www/wwwroot
yum install -y unzip
unzip h5-to-app.zip -d h5-to-app

7.4 验证文件结构

ls -la /www/wwwroot/h5-to-app/
# 应该看到:server/  web/  deploy/ 等目录

ls -la /www/wwwroot/h5-to-app/server/
# 应该看到:src/  tools/  .env.example  package.json 等

ls -la /www/wwwroot/h5-to-app/web/dist/
# 应该看到:assets/  index.html 等文件

7.5 设置目录权限

chown -R root:root /www/wwwroot/h5-to-app
chmod -R 755 /www/wwwroot/h5-to-app

# 确保上传和构建目录可写
chmod -R 777 /www/wwwroot/h5-to-app/server/uploads
chmod -R 777 /www/wwwroot/h5-to-app/server/builds
chmod -R 777 /www/wwwroot/h5-to-app/server/data

八、配置环境变量(.env)

8.1 创建 .env 文件

  1. 在宝塔文件管理器中,进入 /www/wwwroot/h5-to-app/server/ 目录
  2. 找到 .env.example 文件
  3. 右键 → 「复制」,将其复制为 .env(在同一目录下)
  4. 右键新创建的 .env 文件 → 「编辑」

8.2 编辑 .env 文件内容

# ===== 服务配置 =====
PORT=3000
NODE_ENV=production

# ===== JWT 密钥(用于用户登录认证,请用复杂的随机字符串) =====
JWT_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0

# ===== 存储路径 =====
UPLOAD_DIR=./uploads
BUILD_DIR=./builds

# ===== 数据库类型(mysql 表示使用 MySQL) =====
DB_TYPE=mysql

# ===== MySQL 数据库配置(填写你在第六步创建的数据库信息) =====
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=h5app
MYSQL_PASSWORD=你创建数据库时生成的密码
MYSQL_DATABASE=h5app

# ===== 文件大小限制 =====
MAX_FILE_SIZE=10485760
配置项说明
PORT服务运行端口,默认 3000
JWT_SECRET非常重要! 用于加密用户登录 token,请改成一个长且复杂的随机字符串。可用 openssl rand -hex 32 生成
DB_TYPE设为 mysql 使用 MySQL 数据库
MYSQL_HOST数据库主机,宝塔默认是 localhost
MYSQL_PORT数据库端口,默认 3306
MYSQL_USER数据库用户名
MYSQL_PASSWORD数据库密码
MYSQL_DATABASE数据库名称

8.3 生成随机 JWT 密钥

openssl rand -hex 32
# 输出类似:7f3a8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0

九、安装项目依赖

9.1 打开终端

方式一:宝塔面板终端 — 点击宝塔面板左侧 「终端」 菜单

方式二:SSH 连接 — 使用 XShell / PuTTY 连接到服务器

9.2 进入项目目录并安装依赖

# 进入后端目录
cd /www/wwwroot/h5-to-app/server

# 确认 npm 使用国内镜像
npm config set registry https://registry.npmmirror.com

# 安装生产环境依赖
npm install --production
首次安装大约需要 2-5 分钟。如果看到 WARN 警告信息一般可以忽略,只要没有 ERR! 错误就行。如果 sharp 安装失败,尝试:npm install sharp --build-from-source

十、初始化数据库表

如果你已经在第六步通过 phpMyAdmin 导入了 SQL,这一步可以跳过。

如果项目中存在迁移脚本,可以尝试运行:

cd /www/wwwroot/h5-to-app/server
node src/db/migrate.js

十一、使用 PM2 启动服务

11.1 使用 PM2 启动

# 进入后端目录
cd /www/wwwroot/h5-to-app/server

# 使用 ecosystem 配置文件启动服务
pm2 start ecosystem.config.js

11.2 查看服务状态

pm2 status

正常输出应该是 status 列显示 online。如果是 errored,请查看错误日志。

11.3 查看日志

# 查看实时日志(按 Ctrl+C 退出)
pm2 logs h5-to-app

# 只看最近 50 行
pm2 logs h5-to-app --lines 50

# 查看错误日志
pm2 logs h5-to-app --err

正常启动日志应该包含:

🚀 HTTP 服务已启动: http://localhost:3000
✅ 默认管理员账号已创建: admin / admin123
[MySQL] 数据已加载到缓存

11.4 验证服务是否正常

curl http://localhost:3000/api/health
# 正常返回:{"status":"ok","timestamp":"2026-01-01T00:00:00.000Z"}

11.5 保存 PM2 进程列表(开机自启)

# 保存当前进程列表
pm2 save

# 设置开机自启
pm2 startup
# 如果提示你执行一条命令来设置启动脚本,复制那条命令执行即可

十二、配置 Nginx 反向代理

12.1 在宝塔面板创建网站

  1. 点击宝塔面板左侧 「网站」 菜单
  2. 点击 「添加站点」 按钮
  3. 填写信息:
    • 域名:填写你的域名(如 h5.example.com),如果暂时没有域名,填写服务器的公网IP地址
    • 根目录:默认即可
    • PHP版本:选择「纯静态」(我们不需要 PHP)
  4. 点击 「提交」

12.2 配置 Nginx 反向代理

  1. 「网站」 列表中,找到你刚创建的站点
  2. 点击站点名称或右侧的 「设置」 按钮
  3. 在弹出的设置窗口中,点击左侧的 「配置文件」
  4. 用以下内容替换整个 server 块的内容:
server {
    listen 80;
    server_name 你的域名或IP;

    # 前端静态文件根目录
    root /www/wwwroot/h5-to-app/web/dist;
    index index.html;

    # Gzip 压缩(加速网站加载)
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 1000;

    # 前端路由 - SPA 单页应用回退
    location / {
        try_files $uri $uri/ /index.html;
    }

    # API 接口 - 反向代理到 Node.js 后端
    location /api/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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_cache_bypass $http_upgrade;
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }

    # 上传文件访问
    location /uploads/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
    }

    # 构建产物下载
    location /builds/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
    }

    # 静态资源缓存(浏览器缓存7天)
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 7d;
        add_header Cache-Control "public, immutable";
    }

    # 安全头
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # 限制上传文件大小
    client_max_body_size 100M;
}
请将 server_name 后面的 你的域名或IP 改成你实际的域名或服务器 IP!

12.3 重启 Nginx

nginx -t && nginx -s reload
nginx -t 会检查配置是否有语法错误,如果显示 test is successful 则表示配置正确。

十三、配置域名和SSL证书(可选)

13.1 购买域名

  1. 在域名注册商(如 阿里云万网腾讯云DNSPod)购买一个域名
  2. 在域名管理后台,添加一条 A 记录:主机记录 @(或 h5),记录值填写你的服务器公网 IP

13.2 申请免费 SSL 证书(推荐)

方式一:宝塔面板申请 Let's Encrypt 免费证书

  1. 确保你的域名已解析到服务器 IP
  2. 确保 80 端口可以从外网访问
  3. 在宝塔面板 「网站」 列表中,找到你的站点
  4. 点击 「设置」 → 左侧 「SSL」 标签
  5. 选择 「Let's Encrypt」
  6. 勾选你的域名,点击 「一键申请」
  7. 申请成功后,开启「强制HTTPS」

方式二:手动上传证书

  1. 在宝塔面板 「网站」→「设置」→「SSL」
  2. 选择 「其他证书」
  3. 将证书内容粘贴到「证书(PEM格式)」框,私钥内容粘贴到「密钥(KEY)」框
  4. 点击 「保存」,开启 「强制HTTPS」

十四、访问和验证

14.1 访问网站

打开浏览器,输入 http://你的域名http://你的服务器IP

你应该能看到 H5转APP打包系统的首页。

14.2 登录后台

  1. 在首页点击 「登录」(或访问 http://你的域名/login
  2. 使用默认管理员账号登录:
项目
用户名admin
密码admin123
首次登录后,请立即在后台修改默认密码!

14.3 测试 API 接口

在浏览器中访问 http://你的域名/api/health

正常返回:{"status":"ok","timestamp":"2026-01-01T00:00:00.000Z"}

十五、常用运维命令

PM2 进程管理

pm2 status                    # 查看所有进程状态
pm2 logs h5-to-app            # 查看实时日志(Ctrl+C 退出)
pm2 restart h5-to-app         # 重启服务
pm2 stop h5-to-app            # 停止服务
pm2 delete h5-to-app          # 删除进程
pm2 start ecosystem.config.js # 重新启动
pm2 save                      # 保存进程列表(开机自启)
pm2 monit                     # 监控面板

系统监控

df -h                         # 查看磁盘使用情况
free -h                       # 查看内存使用情况
top                           # 查看 CPU 和进程信息
lsof -i :3000                 # 查看 3000 端口是否被占用

Nginx 管理

nginx -t                      # 测试 Nginx 配置
nginx -s reload               # 重新加载配置
systemctl restart nginx       # 重启 Nginx
tail -f /www/wwwlogs/你的域名.error.log  # 查看错误日志

十六、常见问题排查

问题 1:PM2 启动后状态显示 errored

错误日志示例

Error: connect ECONNREFUSED 127.0.0.1:3306
# 或
Error: ER_ACCESS_DENIED_ERROR for user 'h5app'@'localhost'
# 或
Error: ER_BAD_DB_ERROR Unknown database 'h5app'

排查步骤

# 1. 先看详细错误日志
pm2 logs h5-to-app --err --lines 100

# 2. 检查 .env 文件是否正确
cat /www/wwwroot/h5-to-app/server/.env

# 3. 检查 MySQL 是否运行
systemctl status mysql
# 如果显示 inactive (dead),执行:
systemctl start mysql

# 4. 测试数据库连接
mysql -u h5app -p -h localhost -P 3306 h5app

# 5. 检查端口是否被占用
lsof -i :3000
# 如果有进程占用,杀掉:kill -9 进程ID

# 6. 修复后重启
pm2 restart h5-to-app

常见原因对照表

错误信息原因解决方法
ECONNREFUSED 127.0.0.1:3306MySQL 未启动systemctl start mysql
ER_ACCESS_DENIED_ERROR用户名或密码错误检查 .env 中的 MYSQL_USER 和 MYSQL_PASSWORD
ER_BAD_DB_ERROR数据库不存在检查 .env 中的 MYSQL_DATABASE
EADDRINUSE: address already in use :::3000端口被占用lsof -i :3000 然后 kill -9 进程ID
Cannot find module 'xxx'依赖未安装npm install --production
SyntaxError: Cannot use import statementNode.js 版本太低升级到 Node.js 16+

问题 2:访问网站显示 502 Bad Gateway

# 检查 PM2 进程状态
pm2 status
# 如果没有进程或状态是 errored,说明后端没启动

# 确认后端监听的端口
netstat -tlnp | grep 3000

# 如果后端没启动,重新启动
cd /www/wwwroot/h5-to-app/server
pm2 start ecosystem.config.js

# 测试后端是否响应
curl http://localhost:3000/api/health

问题 3:访问网站显示 Nginx 默认页面

# 检查 Nginx 配置
cat /www/server/panel/vhost/nginx/*.conf
# 确认 root 指向:/www/wwwroot/h5-to-app/web/dist

# 确认 dist 目录存在
ls -la /www/wwwroot/h5-to-app/web/dist/index.html

# 重新加载 Nginx
nginx -t && nginx -s reload

问题 4:数据库连接失败(MySQL 8.0 认证问题)

# MySQL 8.0 的认证方式与旧版不同,需要修改:
mysql -u root -p

# 在 MySQL 命令行中执行:
ALTER USER 'h5app'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';
FLUSH PRIVILEGES;
exit;

问题 5:npm install 安装依赖失败

错误 1:sharp 编译失败

# 安装编译依赖
yum install -y gcc gcc-c++ make python3    # CentOS
apt-get install -y build-essential python3  # Ubuntu

# 清除缓存重试
npm cache clean --force
rm -rf node_modules package-lock.json
npm install --production

错误 2:网络超时

# 设置国内镜像
npm config set registry https://registry.npmmirror.com

# 如果还是超时,用 cnpm
npm install -g cnpm --registry=https://registry.npmmirror.com
cnpm install --production

问题 6:APK 打包失败

错误 1:Java 未安装Error: spawn java ENOENT

yum install -y java-1.8.0-openjdk      # CentOS
apt-get install -y openjdk-8-jdk        # Ubuntu
java -version                           # 验证

错误 2:内存不足FATAL ERROR: JavaScript heap out of memory

# 增加 swap 空间
dd if=/dev/zero of=/swapfile bs=1M count=2048
mkswap /swapfile
swapon /swapfile
echo '/swapfile swap swap defaults 0 0' >> /etc/fstab

问题 7:上传大文件失败

确认 Nginx 配置中有 client_max_body_size 100M;,然后 nginx -t && nginx -s reload

问题 8:宝塔面板打不开

bt default              # 查看面板信息
bt restart              # 重启面板
bt 5                    # 重置面板密码
firewall-cmd --permanent --add-port=8888/tcp  # 放行端口
firewall-cmd --reload

问题 9:iOS IPA 打包失败

# 检查证书文件
ls -la /www/wwwroot/h5-to-app/server/uploads/certs/
# 检查构建日志
pm2 logs h5-to-app --lines 50

问题 10:构建完成后状态显示「失败」

# 查看错误日志
pm2 logs h5-to-app --err --lines 30
# 如果看到 "Incorrect datetime value" 错误,需要更新代码

# 临时修复:在 phpMyAdmin 中执行
# UPDATE builds SET status = 'completed' WHERE status IN ('building', 'failed') AND (apk_path IS NOT NULL OR ipa_path IS NOT NULL);

通用排查流程

# 第1步:看 PM2 日志
pm2 logs h5-to-app --lines 50

# 第2步:看错误日志
pm2 logs h5-to-app --err --lines 50

# 第3步:检查进程状态
pm2 status

# 第4步:检查端口
netstat -tlnp | grep 3000

# 第5步:检查数据库
mysql -u h5app -p -e "SELECT 1"

# 第6步:检查磁盘空间
df -h

# 第7步:检查内存
free -h

# 第8步:重启所有服务
pm2 restart h5-to-app
nginx -s reload

附录 A:完整部署命令速查

# 1. 安装宝塔面板(CentOS)
yum install -y wget && wget -O install.sh https://download.bt.cn/install/install_6.0.sh && sh install.sh

# 2. 在宝塔面板安装 Nginx + MySQL(网页操作)

# 3. 安装 Java
yum install -y java-1.8.0-openjdk

# 4. 安装编译工具
yum install -y gcc gcc-c++ make

# 5. 安装 Node.js
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install 16 && nvm use 16 && nvm alias default 16

# 6. 设置 npm 镜像
npm config set registry https://registry.npmmirror.com

# 7. 安装 PM2
npm install -g pm2

# 8. 上传项目文件到 /www/wwwroot/h5-to-app/

# 9. 设置权限
chmod -R 777 /www/wwwroot/h5-to-app/server/uploads
chmod -R 777 /www/wwwroot/h5-to-app/server/builds
chmod -R 777 /www/wwwroot/h5-to-app/server/data

# 10. 配置 .env
cd /www/wwwroot/h5-to-app/server
cp .env.example .env
# 编辑 .env 填写数据库信息

# 11. 安装依赖
npm install --production

# 12. 导入数据库(在 phpMyAdmin 中执行 SQL)

# 13. 启动服务
pm2 start ecosystem.config.js
pm2 save && pm2 startup

# 14. 配置 Nginx(在宝塔面板操作)
nginx -t && nginx -s reload

附录 B:默认账号信息

项目
后台地址http://你的域名/login
默认管理员用户名admin
默认管理员密码admin123
Node.js 服务端口3000
Nginx 监听端口80(HTTP)/ 443(HTTPS)
MySQL 端口3306
部署完成后,请立即修改默认管理员密码!