CertAgent 证照中台
返回官网
产品能力 功能全景 界面预览 文档中心 返回官网
01 · 部署实施

安装部署手册

从服务器选型、环境准备到宝塔 / Docker / Linux 三种部署方式,再到网页安装向导、定时任务、备份恢复、在线升级与故障排查,按步骤把系统跑到生产可用。

v2.99.x 实施人员 · 客户 IT · 运维 约 60 分钟 15 章
开始阅读
安全提示

本手册包含安装口令与初始管理员账号,仅用于首次部署。系统上线前请立即修改默认密码、关闭或限制安装向导访问,并按第十二章完成安全加固。

一、部署前先弄懂这几件事

1.1 这套系统由哪几部分组成

组成部分 作用 通俗理解
Nginx 网站服务器,负责把浏览器请求转给程序 大楼的「前台」
PHP 8.1 / 8.2 运行业务代码 干活的「员工」
MySQL 5.7 / 8.0 保存客户、人员、证书、费用等全部数据 仓库的「账本」
Redis 7(必需) 保存登录状态、菜单、字典等缓存 员工的「便签本」
前端页面 已经打包好,放在 backend/public/web、backend/public/mobile 已经装修好的「房间」

重要:Redis 是硬性依赖。 系统不会在 Redis 不可用时自动改用文件缓存,而是直接返回 503 并提示检查 Redis。这样设计是为了避免多台服务器登录状态不一致。安装前请务必先把 Redis 跑起来。

1.2 部署完成后你能得到什么

入口 地址示例 用途
PC 管理端 https://cert.example.com/web/ 日常办公主界面
手机 H5 https://cert.example.com/mobile/ 手机浏览器、企业微信内使用
后端接口 https://cert.example.com/api/ 前后端通信、Agent 接入
安装向导 https://cert.example.com/install.php 只在首次安装时使用

直接访问 https://cert.example.com/ 时,系统会按浏览器类型自动跳转到 /web/ 或 /mobile/。

1.3 三个名词,先记住

  • 网站根目录:本系统必须指向 backend/public,不是项目根目录,也不是 backend。这是新手最容易配错的一步。
  • 伪静态:让 /certificate 这类页面地址能正确找到程序。不配置的话,登录后一刷新就 404。
  • 定时任务:服务器每天自动执行一次「证书到期检测」和「政务网进度同步」。不配置的话,到期提醒不会自动发出。

二、服务器与环境要求

2.1 软件版本

软件 要求 说明
操作系统 Linux(CentOS 7+ / Ubuntu 20.04+ / Debian 10+) 生产环境不建议用 Windows
Nginx 1.20 及以上 需要支持伪静态
PHP 8.1 或 8.2(最低 8.1) PHP 7.x 无法运行;8.3 及以上尚未充分验证,生产建议用 8.1/8.2
MySQL 5.7 或 8.0 字符集必须 utf8mb4
Redis 5.0 及以上,推荐 7.x 必须能连通,必须设密码(生产)
浏览器 Chrome / Edge 最新版 不建议 IE

2.2 PHP 扩展(必装)

扩展 用途 缺失后果
pdo_mysql 连接 MySQL 无法安装、无法打开任何页面
mbstring 中文字符处理 中文乱码、Excel 导入失败
fileinfo 上传文件真实类型校验 附件上传失败
gd 登录图形验证码 验证码不显示,无法登录
curl 推送、政务网同步、在线升级 推送和同步失败
dom / libxml Excel 读写 导入导出报错
openssl 加密、HTTPS 请求 密码托管、推送失败
zip 在线升级、备份 在线升级不可用
opcache(建议) 提升 PHP 性能 页面变慢,但不影响使用
redis(可选) 更快的 Redis 客户端 没有时会使用内置 Predis,仍可运行

2.3 PHP 关键参数

在 php.ini 中确认(宝塔在「软件商店 → PHP 8.x → 配置修改」):

memory_limit = 512M
upload_max_filesize = 20M
post_max_size = 24M
max_execution_time = 300
max_input_time = 300
date.timezone = Asia/Shanghai
display_errors = Off
log_errors = On
expose_php = Off

[opcache]
opcache.enable = 1
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 32
opcache.max_accelerated_files = 20000
opcache.validate_timestamps = 0
opcache.revalidate_freq = 0
opcache.save_comments = 1

opcache.validate_timestamps = 0 表示 PHP 不会自动发现代码变化。每次升级或手工改代码后,必须重启 PHP-FPM(宝塔:软件商店 → PHP → 重启;Docker:重启 php 容器)。

2.4 服务器配置建议

规模 账号数 峰值并发 CPU 内存 系统盘 数据盘 带宽
小型 ≤ 50 ≤ 20 2 核 4 GB 40 GB SSD 100 GB SSD 5 Mbps
中型 50–200 ≤ 60 4 核 8 GB 60 GB SSD 300 GB SSD 10 Mbps
大型 200–500 ≤ 150 8 核 16 GB 100 GB SSD 500 GB+ NVMe 20–50 Mbps

磁盘请优先 SSD。附件(证书扫描件、合同、资质图片)是增长最快的部分,建议单独挂数据盘。

2.5 网络与端口

方向 端口/地址 用途
入站 80、443 网站访问
入站 22(建议限制来源 IP) SSH 运维
出站 https://hngcjs.hnjs.henan.gov.cn 河南建筑市场监管平台采集
出站 https://www.hnzwfw.gov.cn 河南政务服务网申报进度同步
出站 https://qyapi.weixin.qq.com 企业微信登录、通讯录、推送
出站 SMTP 服务器端口(25/465/587) 邮件提醒
出站 https://gitee.com 在线升级检查与下载

MySQL 3306、Redis 6379 不要对公网开放。只监听 127.0.0.1 或内网地址。


三、部署前的准备清单

动手前,请先把下面这些信息写在纸上或记事本里:

项目 示例 你的值
服务器公网 IP 123.123.123.123
域名 cert.example.com
域名是否已解析到服务器 是 / 否
服务器 SSH 账号 root
SSH 密码或密钥 —
MySQL root 密码 32 位随机字符串
数据库名 cert_agent
数据库账号 cert_agent
数据库密码 32 位随机字符串
Redis 密码 32 位随机字符串
管理员账号 admin
管理员密码 8–32 位,含字母和数字
站点根目录 /www/wwwroot/cert-agent/backend/public

密码建议统一用密码管理器生成,至少 16 位,包含大小写字母、数字和符号。不要使用 123456、admin123 上线。


四、方式一:宝塔面板部署(最推荐,小白首选)

宝塔面板是图形化服务器管理工具,可以用鼠标完成 90% 的部署工作。以下步骤以宝塔 7.9+ 为例。

4.1 安装宝塔面板

  1. 用 SSH 登录服务器。
  2. 到宝塔官网复制对应系统的安装命令,粘贴执行。
  3. 安装完成后,终端会输出面板地址、用户名、密码,请保存好。
  4. 浏览器打开面板地址,登录。
  5. 首次登录会提示安装运行环境,选择 LNMP(Nginx + MySQL + PHP),不要选 LNMPA 或 LAMP。

4.2 安装软件(软件商店)

在「软件商店」依次安装并等待完成:

软件 版本 备注
Nginx 1.22 或更高 已随 LNMP 安装
MySQL 8.0(或 5.7) 已随 LNMP 安装
PHP 8.2(或 8.1) 必须这个版本
Redis 7.x 必装
phpMyAdmin 任意 可选,方便看数据库

安装 PHP 后,点「设置 → 安装扩展」,确认已安装:

pdo_mysql  mbstring  fileinfo  gd  curl  dom  libxml  openssl  zip  opcache

如果列表里没有 redis 扩展也没关系,系统自带 Predis 客户端。装了会更快。

4.3 调整 PHP 配置

在「软件商店 → PHP 8.2 → 配置修改」中,把第二章 2.3 的参数填进去,保存。

再点「禁用函数」,如果列表里有下面这些,删除它们(表示允许使用):

putenv  proc_open  shell_exec  exec  system  passthru

putenv 被禁用会导致程序读不到 .env,表现为「数据库连接失败」。exec 等函数用于在线升级时调用 mysqldump 备份数据库。

保存后重启 PHP。

4.4 上传代码

方式 A:Git 拉取(推荐,后续可在线上更新)

cd /www/wwwroot
git clone https://gitee.com/kxunyun/cert-expiry-manager.git cert-agent

仓库是私有的,执行时会要求输入 Gitee 账号和密码/私人令牌。如果没有仓库权限,请使用方式 B。

方式 B:上传压缩包

  1. 在宝塔「文件」中进入 /www/wwwroot。
  2. 上传项目压缩包(.zip)。
  3. 右键解压,把目录重命名为 cert-agent。
  4. 确认目录结构如下:
/www/wwwroot/cert-agent/
├── backend/                 ← 后端(重点)
│   ├── public/              ← 网站根目录必须指向这里
│   │   ├── index.php
│   │   ├── install.php
│   │   ├── web/             ← PC 端页面(已打包)
│   │   ├── mobile/          ← 手机端页面(已打包)
│   │   └── uploads/         ← 附件目录
│   ├── app/
│   ├── config/
│   ├── database/
│   ├── runtime/             ← 运行时目录(必须可写)
│   ├── vendor/              ← PHP 依赖(已内置)
│   └── .env.example
├── frontend/                ← PC 端源码(一般不用管)
├── mobile/                  ← 手机端源码(一般不用管)
└── docs/

不需要安装 Composer,也不需要安装 Node.js。 vendor、web、mobile 都已随包提供。

4.5 创建站点

宝塔「网站 → 添加站点」:

配置项 填写
域名 cert.example.com(没有域名可先填服务器 IP)
根目录 /www/wwwroot/cert-agent/backend/public
FTP 不创建
数据库 不创建(安装向导会自动建库)
PHP 版本 PHP-82

创建完成后,点站点「设置」:

  1. 网站目录:运行目录选择 /public(如果宝塔提供该选项)。
  2. 网站目录 → 防跨站攻击(open_basedir):取消勾选。

    项目根目录和 public 不在同一层,开启后程序读不到上级的 .env 和 app/,会直接 500。

  3. 伪静态:粘贴下面内容并保存:
location / {
    index index.php index.html index.htm;
    if (!-e $request_filename) {
        rewrite ^(.*)$ /index.php?s=$1 last;
        break;
    }
}
  1. 配置文件:如果你想进一步优化,可在 server { } 内补充:
client_max_body_size 24m;

gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml image/svg+xml;

fastcgi_connect_timeout 10s;
fastcgi_send_timeout 300s;
fastcgi_read_timeout 300s;

保存后点「重载配置」或重启 Nginx。

4.6 设置目录权限

用 SSH 执行(宝塔站点用户通常是 www):

cd /www/wwwroot/cert-agent/backend
chown -R www:www runtime public/uploads
chmod -R 755 runtime public/uploads

如果站点用户是 nginx 或 apache,把 www:www 换成对应用户。权限不对的表现是:首页 500、验证码不显示、附件上传失败、安装向导提示目录不可写。

4.7 准备数据库(二选一)

做法 A:让安装向导自动建库(最简单)

安装向导会自动执行 CREATE DATABASE,只需要准备一个 MySQL 账号(root 或独立账号)和密码。

做法 B:手工建库(推荐生产环境,权限更小)

宝塔「数据库 → 添加数据库」:

项 值
数据库名 cert_agent
用户名 cert_agent
密码 强随机密码
字符集 utf8mb4

或者用命令行:

CREATE DATABASE `cert_agent` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'cert_agent'@'localhost' IDENTIFIED BY '这里换成强密码';
GRANT ALL PRIVILEGES ON `cert_agent`.* TO 'cert_agent'@'localhost';
FLUSH PRIVILEGES;

生产环境不要用 root 跑业务。独立账号只需对 cert_agent 库有全部权限即可。

4.8 准备 Redis

宝塔「软件商店 → Redis → 设置」:

  1. 确认服务状态为「运行中」。
  2. 在「配置修改」中设置密码:
requirepass 这里换成强密码
bind 127.0.0.1
maxmemory 1gb
maxmemory-policy allkeys-lru
appendonly yes
  1. 保存并重启 Redis。
  2. 命令行验证:
redis-cli -a '你的Redis密码' ping
# 返回 PONG 表示正常

如果服务器上还有别的系统也用 Redis,请给本系统分配独立 DB 编号(如 DB=1)和独立前缀(如 cert:),避免互相清缓存。

4.9 运行网页安装向导

浏览器打开:

http://你的域名/install.php

第一步:环境检测

向导会自动检查 PHP 版本、扩展、目录权限、SQL 文件。所有项目显示绿色「通过」再点下一步。

常见红色项及处理:

提示 处理
PHP 版本过低 把站点 PHP 版本切到 8.2
缺少 gd / fileinfo / pdo_mysql 宝塔 PHP → 安装扩展
目录不可写 执行 4.6 的权限命令
缺少 Redis 客户端 安装 phpredis 扩展,或确认 backend/vendor 完整
SQL 文件不存在 确认 backend/database/init.sql、init_data.sql 已上传

第二步:填写配置

字段 填什么 说明
数据库主机 127.0.0.1 数据库和网站同一台服务器就填这个
端口 3306 默认
数据库名 cert_agent 不存在会自动创建
数据库用户名 cert_agent 或 root 建议独立账号
数据库密码 对应密码 失败后需要重新输入
Redis 主机 127.0.0.1 同机
Redis 端口 6379 默认
Redis 密码 你的 Redis 密码 没设密码可留空
Redis 数据库编号 0 或独立编号 多系统共用时务必区分
Redis 键前缀 cert: 不同部署用不同前缀
管理员账号 admin 登录账号
管理员姓名 系统管理员 显示用
管理员密码 8–32 位,含字母和数字 请立刻记下来

密码里如果包含 $、#、;、引号等特殊字符,系统会按原样写入 .env,不需要手工转义。

点击「开始安装」。向导会依次:

  1. 检测 Redis 读写、过期、删除;
  2. 连接 MySQL;
  3. 创建数据库;
  4. 导入 init.sql(建表);
  5. 导入 init_data.sql(角色、菜单、字典、消息模板、示例数据);
  6. 创建管理员;
  7. 生成 backend/.env;
  8. 生成 backend/runtime/install.lock(安装锁)。

只有 Redis 和数据库都检测通过,才会真正写入。 失败不会生成安装锁,也不会把密码显示在页面上;重新提交时需要重新输入数据库和 Redis 密码。

第三步:完成

页面会显示 PC 端和手机端地址:

  • PC 管理端:http://你的域名/web/
  • 手机 H5:http://你的域名/mobile/

打开 PC 端,用刚才设置的管理员账号登录。

4.10 安装后立刻做的 5 件事

  1. 确认安装锁存在:
ls -l /www/wwwroot/cert-agent/backend/runtime/install.lock
  1. 限制安装器访问(生产建议)。站点「配置文件」加入:
location = /install.php {
    allow 192.168.0.0/16;
    allow 127.0.0.1;
    deny all;
}

安装锁本身已经能阻止重复安装,这一步是额外保护。

  1. 确认 APP_DEBUG = false:查看 backend/.env,安装向导会自动设为 false。

  2. 申请 HTTPS:站点「SSL → Let's Encrypt」,申请后开启「强制 HTTPS」。

  3. 修改 CORS 白名单:编辑 backend/config/security.php,把 cors_allowed_origins 改成你的实际域名:

'cors_allowed_origins' => [
    'https://cert.example.com',
],

不要保留 *,也不要把 127.0.0.1:8000 这类开发地址留在生产配置里。

4.11 配置定时任务(宝塔)

「计划任务 → 添加任务」:

项 值
任务类型 Shell 脚本
任务名称 证书到期检测
执行周期 每天 08:00(或每小时)
脚本内容 见下
cd /www/wwwroot/cert-agent/backend && /www/server/php/82/bin/php think cert:checkexpire --catch-up >> runtime/cron.log 2>&1

再加一条政务网同步:

cd /www/wwwroot/cert-agent/backend && /www/server/php/82/bin/php think gov:sync >> runtime/cron.log 2>&1

PHP 路径以宝塔实际为准,常见为 /www/server/php/82/bin/php。不要用 php 裸命令,定时任务环境里可能找不到。 详细说明见第九章。

4.12 宝塔部署最容易踩的 6 个坑

坑 现象 解决
根目录指到项目根或 backend 首页 404 / 直接下载源码 必须指到 backend/public
没配伪静态 登录后刷新 404 粘贴 4.5 的伪静态
开着防跨站攻击 500,日志提示 open_basedir 关闭 open_basedir
runtime 不可写 500、验证码空白 chown -R www:www runtime
PHP 版本是 7.4 500 / 语法错误 切到 8.1 或 8.2
Redis 没启动或密码错 页面 503,提示 Redis 不可用 启动 Redis、核对密码,执行 php think redis:check

五、方式二:Docker 一键部署

适合有 Docker 基础的团队。Docker 方式不使用网页安装器,首次启动会自动建库并导入数据。

5.1 前提

  • 已安装 Docker 24+ 与 Docker Compose v2;
  • 服务器能拉取 mysql:8.0、redis:7-alpine、nginx:alpine 镜像;
  • 80/8080 端口未被占用。

5.2 配置环境变量

cd 项目目录/docker
cp .env.example .env

编辑 docker/.env,至少修改这三项:

MYSQL_ROOT_PASSWORD='换成强随机密码'
REDIS_PASSWORD='换成另一个强随机密码'
GOV_PASSWORD_KEY='换成32位以上随机字符串'

其余可选项:

变量 默认 说明
MYSQL_DATABASE cert_agent 数据库名
MYSQL_PORT 3306 只绑定宿主机 127.0.0.1
REDIS_PORT 6379 Redis 端口(不映射到宿主机)
REDIS_DB 0 Redis 库号
REDIS_PREFIX cert: 键前缀
HTTP_PORT 8080 对外访问端口
HTTP_BIND 0.0.0.0 生产建议改成内网 IP 或 127.0.0.1,由外层 Nginx 转发
MYSQL_MEM_LIMIT 3g MySQL 内存上限
PHP_MEM_LIMIT 2g PHP 内存上限
REDIS_MEM_LIMIT 1g Redis 内存上限

密码包含 $ 时,用单引号包住整个值,例如 MYSQL_ROOT_PASSWORD='a$b#c'。

5.3 启动

cd docker
docker compose up -d --build
docker compose ps

首次启动会:

  1. 启动 MySQL 并自动导入 backend/database/init.sql、init_data.sql;
  2. 启动 Redis 并设置密码;
  3. PHP 容器安装依赖(使用内置 vendor 卷)并等待 MySQL/Redis 健康;
  4. Nginx 等待 PHP 的 Redis 读写健康检查通过后启动;
  5. scheduler 容器每小时执行一次到期检测和政务网同步。

5.4 访问

入口 地址
PC 管理端 http://服务器IP:8080/web/
手机 H5 http://服务器IP:8080/mobile/
接口 http://服务器IP:8080/api/

管理员账号:admin / admin123(首次登录后立即修改)。

Docker 的 Nginx 配置默认对 /install.php 返回 404,这是有意为之。不要尝试在 Docker 环境运行网页安装器覆盖已有数据库。

5.5 常用运维命令

cd docker

# 查看状态
docker compose ps

# 查看日志
docker compose logs -f php
docker compose logs -f nginx
docker compose logs -f scheduler

# 重启
docker compose restart php nginx

# 停止(保留数据)
docker compose down

# 停止并删除数据卷(危险,会清空数据库和 Redis)
docker compose down -v

# 进入 PHP 容器执行命令
docker compose exec php php think redis:check
docker compose exec php php think cert:checkexpire --dry-run

5.6 Docker 方式升级

cd docker
# 先备份数据库(见第十章)
git pull
docker compose up -d --build
docker compose restart php nginx

opcache.validate_timestamps=0,不重启 PHP 容器不会生效。

5.7 Docker 注意事项

  • MySQL 数据在 mysql_data 卷,Redis 在 redis_data 卷,不要随意执行 down -v。
  • Redis 不映射宿主机端口,只能容器内访问,这是安全设计。
  • 生产环境建议在 Docker 外再套一层 Nginx 做 HTTPS,HTTP_BIND 设为 127.0.0.1。
  • GOV_PASSWORD_KEY 一旦设置不要更改,否则已保存的政务网申报密码无法解密。

六、方式三:Linux 手工部署(Nginx + PHP-FPM)

适合不用宝塔、不用 Docker 的标准化运维环境。以下以 Ubuntu 22.04 + PHP 8.2 为例,CentOS 请用 dnf 替换 apt。

6.1 安装软件

sudo apt update
sudo apt install -y nginx mysql-server redis-server \
  php8.2-fpm php8.2-cli php8.2-mysql php8.2-mbstring php8.2-xml \
  php8.2-gd php8.2-curl php8.2-zip php8.2-redis php8.2-opcache

确认版本:

php -v          # 应为 8.2.x
nginx -v
mysql --version
redis-server --version

6.2 创建运行用户与目录

sudo useradd -r -s /sbin/nologin certagent || true
sudo mkdir -p /var/www/cert-agent
sudo chown -R certagent:certagent /var/www/cert-agent

把代码放到 /var/www/cert-agent,确认 backend/public 存在。

6.3 配置 PHP-FPM

编辑 /etc/php/8.2/fpm/pool.d/www.conf:

user = certagent
group = certagent

pm = dynamic
pm.max_children = 40
pm.start_servers = 8
pm.min_spare_servers = 8
pm.max_spare_servers = 20
pm.max_requests = 800
request_terminate_timeout = 300s

4C8G 用 40;2C4G 取一半;8C16G 且 MySQL 同机取 60。pm.max_children 必须小于 MySQL max_connections(建议后者为前者的 1.5 倍以上)。

修改 /etc/php/8.2/fpm/php.ini,填入第二章 2.3 的参数,然后:

sudo systemctl restart php8.2-fpm

6.4 配置 MySQL

CREATE DATABASE `cert_agent` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'cert_agent'@'127.0.0.1' IDENTIFIED BY '强密码';
GRANT ALL PRIVILEGES ON `cert_agent`.* TO 'cert_agent'@'127.0.0.1';
FLUSH PRIVILEGES;

/etc/mysql/mysql.conf.d/mysqld.cnf 建议:

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = '+08:00'
max_connections = 200
innodb_buffer_pool_size = 2G
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = 1
wait_timeout = 600

重启 MySQL:

sudo systemctl restart mysql

6.5 配置 Redis

编辑 /etc/redis/redis.conf:

bind 127.0.0.1
requirepass 换成强密码
maxmemory 1gb
maxmemory-policy allkeys-lru
appendonly yes
sudo systemctl restart redis-server
redis-cli -a '强密码' ping   # PONG

6.6 手工导入数据库

cd /var/www/cert-agent/backend

mysql -h 127.0.0.1 -u cert_agent -p cert_agent < database/init.sql
mysql -h 127.0.0.1 -u cert_agent -p cert_agent < database/init_data.sql

必须用 utf8mb4 导入,否则消息模板里的 emoji 会失败。init_data.sql 开头已包含 SET NAMES utf8mb4;。

导入后默认管理员为 admin / admin123,请立即登录修改。

6.7 手工写 .env

cd /var/www/cert-agent/backend
cp .env.example .env

编辑 .env:

APP_DEBUG = false
APP_TRACE = false

[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = cert_agent
USERNAME = cert_agent
PASSWORD = "你的数据库密码"
HOSTPORT = 3306
CHARSET = utf8mb4
PREFIX = ""

[REDIS]
HOST = "127.0.0.1"
PORT = 6379
PASSWORD = "你的Redis密码"
DB = 0
PREFIX = "cert:"

值用双引号包住,密码里的 #、;、$ 会按原样读取。 手工部署不需要创建 runtime/install.lock;如果你希望顺便封掉安装向导,可以手工创建该文件。

验证 Redis:

cd /var/www/cert-agent/backend
php think redis:check

6.8 配置 Nginx 站点

新建 /etc/nginx/sites-available/cert-agent.conf:

server {
    listen 80;
    server_name cert.example.com;
    root /var/www/cert-agent/backend/public;
    index index.php index.html;

    client_max_body_size 24m;
    server_tokens off;

    gzip on;
    gzip_vary on;
    gzip_comp_level 5;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml image/svg+xml;

    # PC 端
    location /web/ {
        try_files $uri $uri/ /web/index.html;
    }
    location = /web/index.html {
        add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0" always;
    }
    location /web/assets/ {
        add_header Cache-Control "public, max-age=31536000, immutable" always;
    }

    # 手机端
    location /mobile/ {
        try_files $uri $uri/ /mobile/index.html;
    }
    location = /mobile/index.html {
        add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0" always;
    }
    location /mobile/assets/ {
        add_header Cache-Control "public, max-age=31536000, immutable" always;
    }

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_read_timeout 300s;
    }

    # 生产建议限制安装器
    location = /install.php {
        allow 127.0.0.1;
        allow 192.168.0.0/16;
        deny all;
    }
}

启用并重载:

sudo ln -s /etc/nginx/sites-available/cert-agent.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

6.9 权限

sudo chown -R certagent:certagent /var/www/cert-agent/backend/runtime /var/www/cert-agent/backend/public/uploads
sudo chmod -R 755 /var/www/cert-agent/backend/runtime /var/www/cert-agent/backend/public/uploads

6.10 HTTPS

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d cert.example.com

开启 HTTPS 后,记得把 backend/config/security.php 的 CORS 白名单改成 https://cert.example.com。

6.11 定时任务

sudo crontab -u certagent -e

加入:

0 8 * * * cd /var/www/cert-agent/backend && /usr/bin/php think cert:checkexpire --catch-up >> runtime/cron.log 2>&1
30 8 * * * cd /var/www/cert-agent/backend && /usr/bin/php think gov:sync >> runtime/cron.log 2>&1

6.12 访问

  • PC:http://cert.example.com/web/
  • 手机:http://cert.example.com/mobile/

七、网页安装向导逐项说明

7.1 它能做什么

安装向导会:

  • 检查 PHP 版本、扩展、目录权限;
  • 实测 Redis 读写、过期、删除(不是只连一下);
  • 连接 MySQL 并创建数据库(若不存在);
  • 导入建表 SQL 与初始化数据;
  • 创建管理员账号(bcrypt 加密);
  • 生成 backend/.env;
  • 生成安装锁 backend/runtime/install.lock。

7.2 字段校验规则

字段 规则
数据库主机 必填
端口 1–65535
数据库名 1–64 位字母、数字、下划线
数据库用户名 必填
管理员账号 必填,建议 admin
管理员密码 8–32 位,必须同时包含字母和数字
Redis 主机/端口 必填,端口 1–65535
Redis 密码 可空;有密码必须正确
Redis DB ≥ 0 的整数
Redis 键前缀 必填,最多 128 字节,不能为空

7.3 安装锁与重装

  • 安装成功后生成 backend/runtime/install.lock。
  • 再次访问 install.php 会提示已安装并拒绝执行。
  • 重装前:先备份数据库与附件,再删除 backend/runtime/install.lock,然后重新访问安装向导。
  • 重装会覆盖数据库中的同名表,不要在没有备份的情况下操作。

7.4 安装失败怎么办

提示 原因 处理
数据库连接失败 账号/密码/端口错,或 MySQL 未启动 用 mysql -h ... -u ... -p 手动验证
数据库名不合法 含横线、中文、空格 只用字母数字下划线
Redis 检测失败 服务未启动、密码错、DB 不存在、ACL 不允许 SETEX/DEL redis-cli -a 密码 ping,再执行 php think redis:check
缺少 Redis 客户端 既没有 phpredis,也没有 vendor/predis 安装扩展或恢复 backend/vendor
目录不可写 权限不对 chown -R www:www backend/runtime
导入 SQL 失败 字符集不对、MySQL 版本过低、SQL 文件缺失 用 utf8mb4 建库,确认文件完整

八、安装完成后的首次配置

按下面顺序配置,可以少走很多弯路。

8.1 修改管理员密码

登录后点右上角头像 →「个人中心」→「修改密码」。

如果沿用了 admin123,请立刻修改。密码要求与安装时一致:8–32 位,含字母和数字。

8.2 系统信息设置

「系统管理 → 系统信息设置」:

配置 建议
系统名称 你的公司名 + 证照管理系统
系统简称 侧边栏显示用,2–4 个字
系统 Logo 上传公司 Logo,或留空显示文字
运营主体 公司全称
联系方式 客服电话/微信
版权信息、备案号 按实际填写
站点根地址 https://cert.example.com
移动端 H5 地址 https://cert.example.com/mobile
敏感数据脱敏 建议开启
可查看明文的角色 只勾选超级管理员
登录超时 默认 3 小时,可按需调整
信任设备有效期 默认 3 天

移动端 H5 地址会影响推送消息里的「查看详情」链接,务必填写外网可访问地址。

8.3 建部门、建账号、配角色

  1. 「组织架构 → 部门管理」建立部门树(如:总经办、证照部、项目部、财务部)。
  2. 「组织架构 → 角色管理」确认内置角色: - 超级管理员 - 证照管理员 - 项目配证专员 - 财务专员 - 企业查看者 - 只读观察员
  3. 「组织架构 → 账号权限管理」新建员工账号,选择部门、角色、数据范围。
  4. 客户企业账号:角色选「企业查看者」,并在「可管企业」中关联对应企业。

客户账号只能看自己企业的数据,且是只读。内部员工按岗位分配角色即可。

8.4 录入基础数据

建议顺序:

  1. 企业客户:新增或 Excel 导入客户企业。
  2. 人员档案:新增或导入持证人员,补全身份证、电话、社保状态。
  3. 证照台账:为人员新增证书,选择证书类型/专业、到期日、扫描件。
  4. 证书借调:把证书借给客户企业,填写期限、费用、合同。
  5. 项目配证:建项目、填证件需求,再用智能匹配选人。

证书只归属持证人,企业通过「借调」使用证书。这是本系统最核心的业务模型,录入时不要搞反。

8.5 配置提醒与推送

  1. 「系统管理 → 提醒规则设置」:确认全局默认提醒节点(1 年 / 6 月 / 3 月 / 2 月 / 1 月 / 15 天 / 7 天 / 3 天 / 1 天)和提醒方式。
  2. 「推送中心 → 推送渠道管理」:新增短信 / 邮件 / 企微机器人 / 企微应用 / 公众号渠道,点「测试推送」验证。
  3. 「推送中心 → 企业接收人」:配置全局接收人和各企业接收人。
  4. 「推送中心 → 消息模板管理」:按场景 × 渠道检查模板内容。
  5. 「推送中心 → 提醒中心」:点「推送体检」,确认没有阻断项。

没有配置任何渠道时,系统会「模拟发送」并写日志,不会真正发出消息。上线前务必用「测试推送」验证一次。

8.6 配置企微(可选)

「系统管理 → 企微登录配置」填写 CorpID、AgentID、Secret,保存后点「测试连接」。

「组织架构 → 企微通讯录」可同步成员并绑定/创建系统账号。

8.7 配置政务网进度(可选)

  1. 「系统管理 → 字典管理」确认「政务网业务类型」「政务网平台」字典。
  2. 「政务网进度 → 申报进度」新增申报记录,填写申报号和申报密码。
  3. 点「同步」验证能否取回环节。
  4. 配置 gov:sync 定时任务。

申报密码使用 AES-256-GCM 加密存储,列表只显示掩码。更换 GOV_PASSWORD_KEY 会导致旧密码无法解密。

8.8 自检一遍

  • [ ] 首页 KPI 正常显示,没有红色报错
  • [ ] 新增一个人员、一本证书、一条借调,能保存
  • [ ] 上传一个附件,能预览/下载
  • [ ] 导出一个 Excel,文件名中文正常
  • [ ] 「系统信息 → 清除缓存」执行成功
  • [ ] 推送渠道「测试推送」成功
  • [ ] 手动执行一次到期检测,日志正常
  • [ ] 手机打开 /mobile/ 能登录

九、定时任务配置

9.1 三个命令

命令 作用 建议频率
php think cert:checkexpire 证书到期检测、借调到期处理、生成提醒并推送 每天 1 次;加 --catch-up 可每小时
php think gov:sync 政务网申报进度同步 每天 1 次(内部 20 小时幂等)
php think redis:check Redis 连通性自检 排障时手动执行

9.2 cert:checkexpire 参数

参数 作用
无参数 正常执行:扫描证书、生成提醒、推送、标记过期
--catch-up 补发最近 3 天漏跑的提醒节点,按「证书 + 节点 + 日期」去重
--dry-run 只体检不写库,用于确认会命中哪些提醒

示例:

cd /www/wwwroot/cert-agent/backend

# 每天正常跑
/www/server/php/82/bin/php think cert:checkexpire

# 每小时跑并补发(推荐,任务停摆也不漏)
/www/server/php/82/bin/php think cert:checkexpire --catch-up

# 只看会发什么,不写库
/www/server/php/82/bin/php think cert:checkexpire --dry-run

它会:

  • 把已过到期日、状态仍为「正常」的证书自动标记为「已过期」,写入状态变更日志;
  • 把已过结束日、状态仍为「借调中」的借调标记为「已到期」,并生成提醒;
  • 按提醒节点生成站内提醒,并通过已启用渠道推送;
  • 单条脏数据只跳过并记录,不会让整次任务失败;
  • 退出码非 0 表示存在推送失败或任务异常。

9.3 gov:sync 参数

参数 作用
无参数 同步所有未办结、未归档的申报(20 小时内不重复)
--force 忽略 20 小时限制,强制同步
--all 包含已归档记录
--id=123 只同步指定 ID
/www/server/php/82/bin/php think gov:sync
/www/server/php/82/bin/php think gov:sync --force
/www/server/php/82/bin/php think gov:sync --id=123

9.4 验证定时任务是否真的执行

  1. 看日志:
tail -n 100 /www/wwwroot/cert-agent/backend/runtime/cron.log
  1. 看页面:「推送中心 → 提醒中心 → 到期检测执行结果」,有执行时间、扫描数、推送数。
  2. 看「政务网进度 → 申报进度 → 执行记录」,有每次同步的结果。
  3. 手动跑一次命令,确认退出码为 0:
cd /www/wwwroot/cert-agent/backend
/www/server/php/82/bin/php think cert:checkexpire --dry-run
echo $?

9.5 定时任务常见问题

现象 原因 处理
日志为空,任务显示成功 PHP 路径不对,命令没真正执行 用绝对路径,先手动执行
Could not open input file: think 没有 cd 到 backend 脚本里加 cd
报 Redis 连接失败 定时任务环境读不到 .env 或 Redis 密码错 用同版本 PHP CLI 执行 php think redis:check
报函数被禁用 exec/proc_open 被禁用 宝塔 PHP 禁用函数里删除
推送没收到 渠道/接收人/提醒规则未配好 用「推送体检」逐项排查
任务重复推送 同时配了每小时和每天两条 只保留一条,或用 --catch-up 去重

十、备份与恢复

10.1 必须备份的内容

内容 路径/方式 频率
数据库 mysqldump 每天
附件 backend/public/uploads/ 每天
配置文件 backend/.env 每次修改后
政务网密钥 .env 中的 GOV_PASSWORD_KEY 修改前
代码 Git 仓库或整包 每次升级前

backend/runtime/ 下还有日志、导出临时文件、vault/。runtime/vault/ 如果存有加密文件,也要纳入备份。

10.2 数据库备份脚本

把数据库账号密码放到 /root/.my.cnf:

[client]
user=cert_agent
password=你的数据库密码
chmod 600 /root/.my.cnf

每日备份:

mkdir -p /backup/db
mysqldump --defaults-extra-file=/root/.my.cnf \
  --single-transaction --quick --routines --triggers \
  cert_agent | gzip > /backup/db/cert_agent_$(date +%F).sql.gz

rsync -a --delete /www/wwwroot/cert-agent/backend/public/uploads/ /backup/upload/
find /backup/db -name '*.sql.gz' -mtime +14 -delete

加入 crontab:

30 2 * * * /bin/bash /root/backup-certagent.sh >> /var/log/backup-certagent.log 2>&1

10.3 恢复步骤

# 1. 停应用(避免写入)
systemctl stop php8.2-fpm nginx

# 2. 恢复数据库(建议先建空库)
mysql -u root -p -e "DROP DATABASE IF EXISTS cert_agent; CREATE DATABASE cert_agent DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
gunzip < /backup/db/cert_agent_2026-11-01.sql.gz | mysql -u root -p cert_agent

# 3. 恢复附件
rsync -a /backup/upload/ /www/wwwroot/cert-agent/backend/public/uploads/

# 4. 清缓存并重启
cd /www/wwwroot/cert-agent/backend
php think clear
systemctl start php8.2-fpm nginx

php think clear 会清理缓存,可能导致所有用户重新登录。

10.4 恢复演练

每季度至少做一次:

  1. 在测试服务器导入最近一份备份;
  2. 确认表数量正常(新建 70 张,运行后自愈表会出现,共 72 张左右);
  3. 确认管理员能登录;
  4. 随机打开 3 本证书,确认附件能下载;
  5. 执行一次 cert:checkexpire --dry-run。

只有备份文件、没验证过恢复,等于没有备份。


十一、在线升级

11.1 前提条件

条件 说明
Gitee 私人令牌 私有仓库必须配置,否则检测返回 404
[UPGRADE] 配置 在 backend/.env 中
代码可写 PHP 进程对项目目录有写权限
zip 扩展 解压升级包
curl 扩展 下载升级包
exec/proc_open/shell_exec 至少一个 调用 mysqldump 备份
mysqldump、mysql 数据库备份与恢复

配置示例(backend/.env):

[UPGRADE]
GITEE_OWNER = "kxunyun"
GITEE_REPO = "cert-expiry-manager"
GITEE_TOKEN = "你的Gitee私人令牌"
; 可选:手工指定 mysqldump / mysql 路径
; MYSQLDUMP = "/usr/bin/mysqldump"
; MYSQL = "/usr/bin/mysql"

Gitee 令牌在「Gitee → 设置 → 私人令牌」生成,勾选 projects 读权限。令牌只保存在服务器 .env,不要发给别人,也不要提交到 Git。

11.2 页面升级流程

  1. 「系统管理 → 在线升级」。
  2. 查看「当前版本」和「环境能力检测」(zip / curl / exec / 可写)。
  3. 点「检查新版本」。
  4. 有新版时页面显示版本号、来源、更新内容。
  5. 点「立即备份」(强烈建议)。
  6. 点「执行升级」,等待进度完成。
  7. 页面提示完成后,重启 PHP-FPM(或重启 php 容器)。
  8. 强制刷新浏览器(Ctrl/Cmd + Shift + R)。

11.3 上传升级包

没有外网或没有 Gitee 令牌时:

  1. 拿到官方升级包(.zip)。
  2. 在升级页「上传升级包」区域拖入或选择文件。
  3. 点「上传并校验」。
  4. 校验通过后点「执行升级」。

11.4 升级失败回滚

  1. 进入「在线升级 → 备份管理」。
  2. 找到升级前的备份,点「恢复」。
  3. 恢复会还原代码与数据库;附件不在升级包内,一般不受影响。
  4. 恢复后重启 PHP-FPM。

升级前手工备份一次数据库,永远是成本最低的保险。

11.5 升级注意事项

  • 升级前确认磁盘剩余空间 ≥ 升级包大小的 3 倍。
  • 升级期间不要多人同时操作。
  • 升级后必须重启 PHP-FPM,否则 OPcache 仍执行旧代码。
  • 升级后如页面空白,先强制刷新;仍空白请看 backend/runtime/log/ 当日日志。
  • 跨大版本升级前,先阅读升级页的「更新内容」。

十二、性能与安全加固

12.1 Nginx

worker_processes auto;
worker_rlimit_nofile 65535;

events {
    use epoll;
    worker_connections 4096;
    multi_accept on;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    client_max_body_size 24m;
    server_tokens off;

    gzip on;
    gzip_vary on;
    gzip_comp_level 5;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml application/json application/javascript application/xml image/svg+xml;

    fastcgi_connect_timeout 10s;
    fastcgi_send_timeout 300s;
    fastcgi_read_timeout 300s;
}

12.2 MySQL

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-time-zone = '+08:00'
max_connections = 200
innodb_buffer_pool_size = 2G
innodb_buffer_pool_instances = 2
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = 1
table_open_cache = 2000
tmp_table_size = 64M
max_heap_table_size = 64M
wait_timeout = 600
slow_query_log = 1
long_query_time = 1

innodb_buffer_pool_size 建议为物理内存的 50%–60%。4G 机器设 1G,8G 机器设 2–3G。

12.3 Redis

maxmemory 1gb
maxmemory-policy allkeys-lru
appendonly yes
appendfsync everysec
save 900 1
timeout 0
tcp-keepalive 300

12.4 安全清单

  • [ ] 全站 HTTPS,HTTP 自动跳转 HTTPS
  • [ ] backend/.env 中 APP_DEBUG=false、APP_TRACE=false
  • [ ] display_errors=Off
  • [ ] CORS 白名单改成实际域名,不用 *
  • [ ] 默认管理员密码已修改,演示账号已删除
  • [ ] 数据库使用独立账号,不用 root
  • [ ] MySQL、Redis 不暴露公网,Redis 必须设密码
  • [ ] 服务器防火墙只放行 80/443 和受控 SSH
  • [ ] backend/runtime/ 权限最小化,runtime/vault/ 纳入备份
  • [ ] 安装器已限制内网访问
  • [ ] 定期检查磁盘使用率(80% 告警)、MySQL 慢查询、Redis 内存、5xx 比例
  • [ ] 每季度做一次备份恢复演练

十三、上线验收清单

安装完成后,逐项打勾:

基础访问

  • [ ] https://域名/web/ 能打开登录页
  • [ ] https://域名/mobile/ 能打开手机端
  • [ ] 直接访问 https://域名/ 能自动分流
  • [ ] 登录页验证码能显示、能刷新
  • [ ] 管理员能登录,登录后能正常退出

核心业务

  • [ ] 新增企业成功
  • [ ] 新增人员成功,身份证/手机号正常
  • [ ] 新增证书成功,证书类型/专业联动正常
  • [ ] 新增借调成功,冲突提示正常
  • [ ] 新增项目、填证件需求、智能匹配能出结果
  • [ ] 上传证书扫描件成功,能预览/下载
  • [ ] 新增费用、结算、批量打印正常

数据与导出

  • [ ] 人员/企业/证书导入模板能下载
  • [ ] Excel 导入预览、失败名单正常
  • [ ] 证书/企业/人员/费用导出正常,中文文件名不乱码
  • [ ] 回收站能恢复删除的数据

提醒与推送

  • [ ] 推送渠道「测试推送」成功
  • [ ] 企业接收人已配置
  • [ ] 提醒规则已启用
  • [ ] 「推送体检」无阻断项
  • [ ] 手动执行到期检测,有执行记录

系统

  • [ ] 定时任务已配置,日志有输出
  • [ ] 政务网同步(如启用)能成功
  • [ ] 「清除缓存」执行成功
  • [ ] 操作日志有记录
  • [ ] 登录日志有记录
  • [ ] 在线升级「环境能力检测」全部通过(如启用)

十四、常见故障排查

14.1 页面打不开

现象 排查顺序
浏览器提示「无法访问」 域名是否解析、服务器是否开机、80/443 是否放行、Nginx 是否启动
502 Bad Gateway PHP-FPM 是否启动、socket 路径是否与 Nginx 一致、PHP-FPM 是否 OOM
504 Gateway Timeout 导入/同步耗时过长;调大 fastcgi_read_timeout、max_execution_time
403 Forbidden 目录权限、index.php 是否存在、Nginx index 配置
404 Not Found 网站根目录是否指到 backend/public、伪静态是否生效
页面空白 强制刷新;看浏览器控制台;看 runtime/log 日志

14.2 500 错误

  1. 临时把 backend/.env 的 APP_DEBUG 改为 true,刷新看具体错误。
  2. 查看 backend/runtime/log/ 当日日志。
  3. 最常见原因: - runtime 不可写; - open_basedir 限制; - PHP 版本低于 8.1; - 缺少扩展(fileinfo、gd、pdo_mysql); - .env 格式错误(值没加引号、有换行)。
  4. 处理完把 APP_DEBUG 改回 false。

14.3 登录后刷新 404

伪静态没生效。检查 Nginx 配置是否有:

location / {
    try_files $uri $uri/ /index.php$is_args$args;
}

宝塔用户检查「站点设置 → 伪静态」是否保存并重载。

14.4 验证码不显示 / 提示验证码错误

  • 确认 gd 扩展已安装;
  • 确认 backend/resource/font/ 下字体文件存在且可读;
  • 确认 runtime 可写;
  • 浏览器时间是否正确(影响验证码有效期判断);
  • 反向代理/多台服务器时,确认会话粘滞或 Redis 正常。

14.5 提示 Redis 不可用(503)

系统不会降级文件缓存,必须修复 Redis:

cd /www/wwwroot/cert-agent/backend
php think redis:check

按提示检查:

  • Redis 是否启动:systemctl status redis;
  • 密码是否正确:redis-cli -a '密码' ping;
  • .env 的 [REDIS] 是否写对;
  • 是否连错 DB 或前缀冲突;
  • 云 Redis 是否允许当前服务器 IP。

修复后重启 PHP-FPM,不需要重装。

14.6 数据库连接失败

  • .env 中 HOSTNAME、DATABASE、USERNAME、PASSWORD、HOSTPORT 是否正确;
  • MySQL 是否启动;
  • 账号是否允许从该主机连接(user@localhost vs user@127.0.0.1);
  • MySQL 8.0 认证插件问题:可临时改为 mysql_native_password;
  • 密码含特殊字符时是否用双引号包住;
  • putenv 是否被禁用。

14.7 上传附件失败

  • upload_max_filesize、post_max_size、Nginx client_max_body_size 是否 ≥ 20M;
  • public/uploads 是否可写;
  • 磁盘是否已满;
  • 文件扩展名是否在白名单内;
  • 如果启用了 WebDAV,检查地址、账号、目录权限,点「测试连接」。

14.8 Excel 导入失败

提示 处理
文件格式不支持 只支持 .xlsx / .xls,且 ≤ 10MB
模板列不匹配 重新下载最新模板,不要删改表头
日期格式错误 按模板格式填 YYYY-MM-DD,不要填 -、0
身份证/手机号格式错误 检查位数与字符
必填项缺失 看预览页的逐行原因,或下载失败名单
导入很慢/超时 分批导入,调大 max_execution_time

14.9 中文乱码

  • 数据库、表、连接字符集都必须是 utf8mb4;
  • 导入 SQL 时使用 SET NAMES utf8mb4;;
  • Nginx/PHP 默认字符集 UTF-8;
  • Excel 导出文件名乱码:确认代码为最新版(已使用 RFC 5987 编码)。

14.10 定时任务不执行

  • 脚本里是否 cd 到 backend;
  • PHP 是否用绝对路径;
  • 执行用户是否有权限读 .env;
  • 手动执行命令是否成功;
  • 看 runtime/cron.log;
  • 宝塔计划任务日志是否显示成功但无输出(多为 PHP 路径错)。

14.11 到期提醒不推送

按顺序排查:

  1. 「推送中心 → 提醒中心 → 推送体检」,看阻断原因;
  2. 是否启用了至少一个推送渠道;
  3. 渠道配置是否完整(短信网关、SMTP、Webhook、企微 Secret);
  4. 是否有启用中的接收人;
  5. 企业提醒规则是否勾选了提醒方式;
  6. 证书剩余天数是否已落到提醒节点;
  7. 定时任务是否执行;
  8. 「推送消息日志」里是否有记录、失败原因是什么。

14.12 政务网同步失败

  • 服务器能否访问 https://www.hnzwfw.gov.cn;
  • 申报号和申报密码是否正确;
  • 平台是否临时维护;
  • 申报是否已办结/归档(归档后不再自动同步);
  • 查看「申报进度 → 执行记录」的具体错误;
  • 用「修复历史环节」从原始响应重新解析。

14.13 企业微信相关失败

  • CorpID、AgentID、Secret 是否正确;
  • 服务器 IP 是否在企业微信可信 IP 中;
  • 回调 URL 是否可公网访问、Token 是否一致;
  • 通讯录同步权限是否已开通;
  • 报 TLS 错误时检查服务器 CA 证书与时间。

14.14 升级后页面空白 / 报错

  1. 强制刷新(Ctrl/Cmd + Shift + R);
  2. 重启 PHP-FPM(OPcache 不自动感知文件变化);
  3. 检查 public/web/assets 是否完整;
  4. 看 runtime/log;
  5. 用备份管理回滚。

十五、附录

15.1 关键目录

路径 说明 是否可写
backend/public/ 网站根目录 只读
backend/public/web/ PC 端构建产物 只读
backend/public/mobile/ 手机端构建产物 只读
backend/public/uploads/ 本机附件 可写
backend/runtime/ 缓存、日志、临时文件 可写
backend/runtime/log/ 应用日志 可写
backend/runtime/export/ 导出临时文件 可写
backend/runtime/vault/ 敏感运行文件 可写,权限最小化
backend/.env 环境配置 只读(仅运维可改)
backend/database/init.sql 建表 SQL 只读
backend/database/init_data.sql 初始化数据 只读

15.2 默认端口

服务 端口
HTTP 80
HTTPS 443
MySQL 3306
Redis 6379
Docker 默认 HTTP 8080

15.3 常用命令速查

# 进入后端目录
cd /www/wwwroot/cert-agent/backend

# Redis 自检
php think redis:check

# 清理本系统前缀下的缓存(会让用户重新登录)
php think redis:check --flush

# 只清理菜单缓存
php think redis:check --flush --ns=menu

# 到期检测(只体检)
php think cert:checkexpire --dry-run

# 到期检测(正常执行)
php think cert:checkexpire

# 到期检测(补发 3 天内漏跑节点)
php think cert:checkexpire --catch-up

# 政务网同步
php think gov:sync

# 政务网强制同步
php think gov:sync --force

# 查看日志
tail -f runtime/log/$(date +%Y%m)/$(date +%d).log

# 重启 PHP-FPM(Ubuntu)
systemctl restart php8.2-fpm

# 重启 Nginx
systemctl reload nginx

15.4 默认账号

场景 账号 密码
网页安装向导创建 你填写 你填写
手工导入 init_data.sql admin admin123

无论哪种方式,首次登录后都必须修改密码。

15.5 内置角色

角色 适用岗位
超级管理员 系统负责人,全部权限
证照管理员 人员、证书、延续、借调、提醒、客户、项目配证、政务网、报名
项目配证专员 项目配证、智能匹配、冲突、属地政策、报名
财务专员 费用台账、收款账户、服务合同
企业查看者 客户企业账号,只看本企业,只读
只读观察员 内部只读查看

角色菜单和按钮权限可在「角色管理」中按需调整。


安装部署到此完成。 如果按本文操作仍无法启动,请准备好以下信息再联系技术支持:

  1. 服务器系统版本、PHP 版本、MySQL 版本、Redis 版本;
  2. 出错页面的截图;
  3. backend/runtime/log/ 下当日日志的最后 100 行;
  4. 是否使用宝塔/Docker、站点根目录、伪静态配置;
  5. 已经尝试过的处理步骤。