完整公开

部署与运维文档

从创建站点到上线安全检查,包含运行环境、数据库、伪静态、Chrome、OSS、AI、任务、备份与排障。

PHP 7.4 / 8.2支持版本
Nginx推荐 Web 服务
MySQL 5.7+数据库

本文档用于将当前程序部署到 Linux 服务器的宝塔面板环境中,并说明后台配置、Chrome 截图依赖、OSS、DeepSeek、计划任务、备份迁移和常见故障排查。

文档中的路径、域名、数据库名、账号密码均为示例,请按实际服务器替换。不要把真实数据库密码、OSS Key、DeepSeek Key 写进文档或公开仓库。


#1. 程序概览

#1.1 技术栈

  • PHP 程序,无需 Node.js 构建。
  • MySQL / MariaDB 数据库。
  • 后台 UI 使用 Tabler Core 1.4.0、Bootstrap 5.3.8 和 Lucide 1.26.0,全部为本地静态资源,不依赖 CDN。
  • 当前后台商业化视觉版本为 V2.5.17,对应 config/app.php 静态资源缓存版本 2.5.35
  • Layui 2.9.7 与 jQuery 3.7.1 继续作为旧业务页面的兼容运行时,不能只因视觉升级而删除。
  • 前台由 index.php 统一分发。
  • 后台入口默认是 admin.php,线上可通过 admin_path 设置隐藏入口,例如 /mali-admin
  • 伪静态依赖 Nginx / Apache rewrite。
  • 截图功能依赖服务器安装 Chrome / Chromium,并要求 PHP 允许执行外部进程。
  • 图片可存储在本地,也可上传到阿里云 OSS。
  • AI 自动分析使用插件 plugins/ai-analyzer,配置项是 DeepSeek API Key。
  • 后台统一任务中心使用 app/cron/cron_worker.php 处理文章采集队列、导航采集流水线、搜索推送队列和素材队列。
  • 后台支持白标品牌配置:基本配置中的后台名称、副标题和主色会作用于登录页、侧栏、按钮和主题变量;首次进入仪表盘时超级管理员可按引导完成品牌、入口、媒体和任务检查。
  • IT之家正文图片通过 /image-proxy 本站代理缓存,避免原图防盗链 403。

#1.2 重要目录

路径说明
index.php前台统一入口
admin.php后台入口
install.php安装向导
install.lock安装锁,存在时禁止重新安装
config/database.php数据库配置
config/app.php程序基础配置与资源版本号
app/核心程序代码
templates/前台 PC / 手机模板
plugins/插件目录
static/uploads/本地上传、截图、缓存生成资源
static/cache/前台缓存、站点地图缓存等
static/logs/程序本地日志
static/vendor/后台 Tabler、Bootstrap、Lucide、Layui、jQuery 等本地第三方依赖
database/schema.sql初始数据库结构与种子数据
app/cron/cron_worker.php唯一建议常驻的站内任务执行器,统一处理采集、素材、搜索推送、自发文章和点击量等任务
IndexNow/搜索推送统一后台搜索推送队列,处理现有链接补推与新增 URL 入队
app/cron/cron_collect.php文章采集兼容脚本,生产环境一般不再单独配置
app/cron/cron_clicks.php点击量汇总兼容/手动排查脚本,生产环境不再单独配置
app/cron/cron_nav_discover.php导航采集兼容/手动脚本,生产环境一般不再单独配置
app/cron/cron_random_today.php随机今日浏览量兼容/手动排查脚本,生产环境不再单独配置
nginx.htaccessNginx 伪静态参考规则
.htaccessApache 访问保护规则

#2. 宝塔环境要求

#2.1 推荐环境

  • 系统:Debian 11/12、Ubuntu 20.04/22.04、CentOS 7、Rocky Linux、AlmaLinux、Alibaba Cloud Linux 均可。
  • Web 服务:Nginx 1.20+ 推荐。
  • PHP:7.4 推荐;PHP 8.0/8.1 通常也可,但上线前必须完整测试。
  • 数据库:MySQL 5.7/8.0 或 MariaDB 10.3+。
  • 宝塔面板:7.x / 8.x 均可。
  • HTTPS:建议开启。

SSH 一键检测命令:

bash
echo "===== 系统 ====="; cat /etc/os-release 2>/dev/null | egrep "PRETTY_NAME|VERSION=" || uname -a; \
echo; echo "===== 宝塔 ====="; /etc/init.d/bt status 2>/dev/null || bt status 2>/dev/null || echo "未检测到宝塔命令"; \
echo; echo "===== Web 服务 ====="; nginx -v 2>&1 || httpd -v 2>/dev/null | head -n 1 || apachectl -v 2>/dev/null | head -n 1 || echo "未检测到 Nginx/Apache"; \
echo; echo "===== PHP ====="; for p in /www/server/php/*/bin/php $(command -v php 2>/dev/null); do [ -x "$p" ] && echo "$p => $($p -r 'echo PHP_VERSION;' 2>/dev/null)"; done | sort -u; \
echo; echo "===== 数据库 ====="; mysql --version 2>/dev/null || /www/server/mysql/bin/mysql --version 2>/dev/null || echo "未检测到 mysql 客户端"; \
echo; echo "===== HTTPS/证书工具 ====="; which openssl >/dev/null 2>&1 && openssl version || echo "未检测到 openssl"

如果输出里能看到宝塔状态、Web 服务版本、PHP 版本、MySQL/MariaDB 版本,说明基础环境已经具备。PHP 版本建议优先使用宝塔站点绑定的版本,不要只看系统默认 php 命令。

#2.2 PHP 必需扩展

在宝塔面板中进入:

软件商店 -> PHP -> 设置 -> 安装扩展

请确认以下扩展已安装或已启用:

  • pdo_mysql:数据库连接必需。
  • curl:抓取、API 请求建议启用。
  • mbstring:中文截取、编码处理必需。
  • fileinfo:图片 MIME 安全检查必需。
  • gd:图片处理、截图压缩建议启用。
  • openssl:HTTPS 请求、签名等需要。
  • json:PHP 通常内置。
  • zip:备份、扩展能力建议启用。

SSH 一键检测命令:

bash
PHP_BIN="${PHP_BIN:-/www/server/php/74/bin/php}"; [ -x "$PHP_BIN" ] || PHP_BIN="$(command -v php)"; \
echo "当前检测 PHP:$PHP_BIN"; "$PHP_BIN" -v | head -n 1; \
echo; echo "===== 扩展检查 ====="; \
for ext in pdo_mysql curl mbstring fileinfo gd openssl json zip; do \
  "$PHP_BIN" -m | grep -qi "^${ext}$" && echo "OK   $ext" || echo "MISS $ext"; \
done

如果站点使用的不是 PHP 7.4,把第一段路径改成对应版本,例如:

bash
PHP_BIN=/www/server/php/81/bin/php

检测结果里出现 MISS 的扩展,需要回到宝塔的 PHP 扩展页面安装或启用。修改扩展后记得重启对应 PHP 服务。

后台也提供检查入口:

系统设置 -> 系统状态

上线后第一件事建议打开这里看 PHP 扩展、数据库、OSS、AI Key、目录可写性是否正常。

#2.3 PHP 函数限制

截图功能需要 PHP 能启动 Chrome 进程。宝塔默认可能禁用部分函数。

进入:

软件商店 -> PHP -> 设置 -> 禁用函数

如果以下函数存在于禁用列表,截图可能失败:

  • proc_open
  • proc_get_status
  • proc_terminate
  • shell_exec
  • exec
  • system
  • passthru

本程序截图核心使用 proc_open,并有 shell 方式兜底。至少要放开 proc_open,建议同时放开 proc_get_statusproc_terminateshell_exec

修改后需要重启 PHP:

软件商店 -> PHP -> 重启


#3. 创建站点

#3.1 宝塔创建网站

进入:

网站 -> 添加站点

建议填写:

  • 域名:www.example.com
  • 根目录:/www/wwwroot/www.example.com
  • PHP 版本:7.4
  • 数据库:创建 MySQL 数据库
  • SSL:后续申请即可

创建后,将程序全部上传到站点根目录,例如:

bash
/www/wwwroot/www.example.com/
├── admin.php
├── index.php
├── app/
│   ├── cron/
│   │   ├── cron_worker.php
│   │   ├── cron_collect.php
│   │   ├── cron_clicks.php
│   │   ├── cron_nav_discover.php
│   │   └── cron_random_today.php
│   └── ScheduledJobs.php
├── config/
├── database/
├── plugins/
├── static/
└── templates/

注意:程序根目录必须是网站运行目录,不建议把程序放到子目录后再用二级路径访问。

#3.2 上传文件注意事项

全新部署时应完整上传程序目录。增量升级时只同步对应版本的变更文件,并先做线上备份;不要直接用本地 config/database.php 覆盖生产数据库配置。

全新部署包括:

  • app
  • config
  • database
  • plugins
  • static
  • templates
  • 根目录 PHP 文件
  • .htaccess
  • nginx.htaccess

后台 UI 版本升级时,至少要同步以下文件,不能只覆盖 CSS:

  • app/admin_functions.php
  • 本次有页面级响应式调整的 app/admin/*.php
  • config/app.php(包含程序版本和静态资源缓存版本)
  • static/css/admin-v3.css
  • static/js/admin/layout.js
  • static/js/admin/ui.js
  • static/css/admin-v4.css
  • static/css/admin-v5.css
  • static/vendor/tabler/1.4.0/
  • static/vendor/bootstrap/5.3.8/
  • static/vendor/lucide/1.26.0/

V2.5.15V2.5.14 增量覆盖时,至少同步 app/admin_functions.phpstatic/js/admin/layout.jsstatic/css/admin-v5.cssconfig/app.php。三组 vendor 版本未变化,不必重复上传;本版本不需要更新数据库结构。

覆盖后如仍看到旧后台,先确认 config/app.phpasset_version 已为 2.5.33,再清理浏览器缓存和站点缓存。后台 UI 改造不涉及数据库结构,单独部署本次版本不需要更新 database/schema.sql


#4. 目录权限

宝塔 Nginx/PHP 常见运行用户是 www

进入 SSH 后执行:

bash
cd /www/wwwroot/www.example.com
chown -R www:www .
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod -R 755 static/uploads static/cache static/logs

如果后台系统状态页提示目录不可写,可临时修复:

bash
chown -R www:www static/uploads static/cache static/logs
chmod -R 755 static/uploads static/cache static/logs

如果仍不可写,检查宝塔的防篡改、open_basedir 或系统权限策略。


#5. 数据库配置与安装

#5.1 全新安装方式

  1. 上传程序。
  2. 确认 config/database.php 可写。
  3. 确认根目录没有 install.lock,否则安装程序会认为已经安装。
  4. 浏览器访问:
text
https://www.example.com/install.php
  1. 按页面填写:
  • 数据库地址:通常是 127.0.0.1
  • 端口:通常是 3306
  • 数据库名:宝塔创建的数据库名
  • 数据库账号:宝塔创建的数据库账号
  • 数据库密码:宝塔创建的数据库密码
  • 后台账号
  • 后台密码
  • 站点名称

安装完成后会生成:

text
install.lock
config/database.php

#5.2 手动配置数据库

也可以直接编辑:

php
<?php

return [
    'host' => '127.0.0.1',
    'port' => 3306,
    'database' => 'your_database',
    'username' => 'your_username',
    'password' => 'your_password',
    'charset' => 'utf8mb4',
];

文件路径:

text
config/database.php

#5.3 导入已有数据库

如果你已经从本地同步了数据库,推荐:

  1. 宝塔创建空数据库。
  2. 在宝塔数据库管理里导入 .sql 文件。
  3. 确认 config/database.php 指向该数据库。
  4. 确认 install.lock 存在。

SSH 导入示例:

bash
mysql -u数据库用户名 -p 数据库名 < /www/backup/malinav.sql

#5.4 数据库字符集

建议数据库和表使用:

text
utf8mb4
utf8mb4_general_ci

否则中文、Emoji、部分图标字符可能保存异常。

#5.5 V2.5.16 广告点击表迁移

  • 本版本新增 ad_click_logs,用于保存广告 ID、点击日期、哈希访客/IP、设备、User-Agent、来源和点击时间。
  • 标准升级流程会在首次请求时由 app/Schema.php 自动执行 CREATE TABLE IF NOT EXISTS,结构版本为 2.5.11
  • 上线前先备份数据库;若自动迁移失败,可从最新 database/schema.sql 单独执行 ad_click_logs 建表语句。
  • 升级后打开 广告运营 -> 点击分析,确认页面可加载,再检查前台广告链接已改写为 /ad-go/{id}
  • 不要用有效广告地址反复测试,以免污染统计;可访问不存在的广告 ID 验证 302 回首页。

#6. Nginx 伪静态配置

程序前台有这些友好 URL:

  • /html/123.html
  • /html/ls/1.html
  • /html/update.html
  • /html/rank.html
  • /html/tools.html
  • /article/420.html
  • /m/article/420.html
  • /go/123
  • /sitemap.xml

这些路径需要交给 index.php 分发。

宝塔进入:

网站 -> 目标站点 -> 设置 -> 伪静态

填入:

nginx
location / {
    try_files $uri $uri/ /index.php?$query_string;
}

location ~ ^/(app|config|database|\.git|\.agents)/ {
    deny all;
}

location = /install.lock {
    deny all;
}

location ~* \.(sql|bak|log|ini|env)$ {
    deny all;
}

location ~ ^/static/(cache|logs)/ {
    deny all;
}

location ~ /\. {
    deny all;
}

项目根目录也提供了 nginx.htaccess 作为参考。

配置后访问测试:

text
https://www.example.com/
https://www.example.com/html/update.html
https://www.example.com/html/rank.html
https://www.example.com/article/420.html

如果这些地址 404,基本就是伪静态没有生效。


#7. Apache 伪静态与保护

如果使用 Apache,根目录 .htaccess 已包含访问保护。

重点作用:

  • 禁止目录索引。
  • 禁止访问 appconfigdatabase.git 等敏感目录。
  • 禁止访问 .sql.bak.log.env 等敏感文件。
  • 禁止访问 install.lock

如果 Apache 下前台伪静态不生效,需要确认站点开启了 AllowOverride All


#8. 后台首次配置

后台默认入口:

text
https://www.example.com/admin.php

登录后建议按顺序配置:

#8.1 系统状态检查

进入:

系统设置 -> 系统状态

重点看:

  • PHP 版本
  • 扩展是否启用
  • 数据库连接
  • OSS 配置状态
  • AI Key 状态
  • static/uploads 是否可写
  • static/cache 是否可写
  • static/logs 是否可写
  • Chrome 路径是否配置

#8.2 基本配置

进入:

系统设置 -> 基本配置

建议配置:

  • 站点标题
  • 副标题
  • 站点描述
  • 关键词
  • 备案号
  • PC 端 Logo
  • 手机端 Logo
  • 出站标识
  • 统计代码
  • 自定义 CSS / JS

#8.3 后台入口

设置项:

text
admin_path

如果不熟悉服务器 rewrite,不建议贸然开启自定义后台入口。保持默认 admin.php 最稳。

如果要隐藏后台入口,请先完整测试新入口可访问,再限制旧入口访问,避免把自己锁在后台外。

#8.4 采集安全

设置项:

  • collect_allowed_hosts
  • collect_block_private
  • collect_timeout_max

建议:

  • collect_block_private 保持开启,防止采集请求访问内网地址。
  • collect_timeout_max 建议 15 秒。
  • collect_allowed_hosts 留空表示允许公网域名,但仍拦截内网和保留地址。

#9. Chrome / Chromium 安装与截图配置

站点编辑页的“自动截图”依赖无头 Chrome。

程序会自动查找以下路径:

  • /bin/google-chrome
  • /bin/google-chrome-stable
  • /usr/bin/google-chrome
  • /usr/bin/google-chrome-stable
  • /usr/local/bin/google-chrome
  • /usr/local/bin/google-chrome-stable
  • /opt/google/chrome/google-chrome
  • /opt/google/chrome/chrome
  • /bin/chromium
  • /bin/chromium-browser
  • /usr/bin/chromium
  • /usr/bin/chromium-browser
  • /usr/local/bin/chromium
  • /usr/local/bin/chromium-browser
  • /snap/bin/chromium

如果自动识别失败,在后台填写:

系统设置 -> 基本配置 -> Chrome 路径

常见值:

text
/usr/bin/google-chrome-stable
/usr/bin/google-chrome
/usr/bin/chromium
/usr/bin/chromium-browser

#9.1 Ubuntu / Debian 安装 Chrome

SSH 执行:

bash
apt update
apt install -y wget gnupg ca-certificates fonts-noto-cjk fonts-liberation
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor -o /usr/share/keyrings/google-linux.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-linux.gpg] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list
apt update
apt install -y google-chrome-stable

验证:

bash
google-chrome-stable --version
which google-chrome-stable

通常输出路径:

text
/usr/bin/google-chrome-stable

把这个路径填入后台 Chrome 路径。

#9.2 CentOS / Rocky / AlmaLinux / Alibaba Cloud Linux 安装 Chrome

SSH 执行:

bash
cat > /etc/yum.repos.d/google-chrome.repo <<'EOF'
[google-chrome]
name=google-chrome
baseurl=https://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl.google.com/linux/linux_signing_key.pub
EOF

yum install -y google-chrome-stable
yum install -y liberation-fonts wqy-microhei-fonts fontconfig

验证:

bash
google-chrome-stable --version
which google-chrome-stable

通常输出路径:

text
/usr/bin/google-chrome-stable

#9.3 使用 Chromium 替代

如果安装 Google Chrome 不方便,可以安装 Chromium。

Ubuntu / Debian:

bash
apt update
apt install -y chromium-browser fonts-noto-cjk
which chromium-browser

有些系统命令是:

bash
which chromium

填入后台的 Chrome 路径即可。

#9.4 截图测试命令

www 用户模拟 PHP 运行环境:

bash
sudo -u www /usr/bin/google-chrome-stable \
  --headless=new \
  --no-sandbox \
  --disable-gpu \
  --disable-dev-shm-usage \
  --window-size=800,600 \
  --screenshot=/tmp/malinav-test.png \
  https://www.example.com

检查文件:

bash
ls -lh /tmp/malinav-test.png

如果能生成大于 1KB 的图片,Chrome 基本正常。

#9.5 截图失败排查

现象可能原因处理
后台提示找不到 Chrome未安装 Chrome 或路径未填执行 which google-chrome-stable,把路径填入后台
提示 proc_open 禁用宝塔 PHP 禁用函数到 PHP 禁用函数里删除 proc_open 并重启 PHP
截图超时目标站打开慢、服务器无法访问目标站服务器 SSH 中 curl -I 目标网址 测试
图片中文乱码或方块缺中文字体安装 fonts-noto-cjkwqy-microhei-fonts
root 下能截图,PHP 不行www 用户权限不同sudo -u www 测试 Chrome
截图目录不可写static/uploads/screenshots 权限不足chown -R www:www static/uploads

程序截图会使用:

  • --headless=new
  • --headless 兜底
  • --no-sandbox
  • --disable-dev-shm-usage
  • --window-size=800,600

截图默认保存到:

text
static/uploads/screenshots/

如果后台开启 OSS,截图成功后会尝试上传到 OSS;OSS 上传失败时会保留本地路径。


#10. OSS 配置

进入:

系统设置 -> 基本配置 -> 媒体与 OSS

字段说明:

字段说明
媒体存储本地存储阿里云 OSS
AccessKey ID阿里云 RAM 用户 AccessKey ID
AccessKey Secret阿里云 RAM 用户 Secret,后台不明文回显
BucketOSS Bucket 名称,只填名称,不带协议
Endpoint外网 Endpoint,例如 oss-cn-hangzhou.aliyuncs.com
OSS 目录建议 mediauploads/media
OSS CDN可选,例如 https://static.example.com,末尾不要加 /

#10.1 RAM 权限建议

不要使用阿里云主账号 AccessKey。建议创建 RAM 子账号,只授予当前 Bucket 需要的权限:

  • oss:PutObject
  • oss:GetObject
  • oss:DeleteObject
  • oss:ListObjects 可选

#10.2 OSS 测试步骤

  1. 保存 OSS 配置。
  2. 进入 文章资讯 -> 媒体库
  3. 上传一张小图片。
  4. 检查图片是否能正常打开。
  5. 进入 系统设置 -> 系统状态 查看 OSS 配置状态。

#10.3 常见 OSS 问题

现象可能原因
上传失败 403AccessKey 权限不足或 Bucket 策略禁止写入
上传成功但图片打不开Bucket 不允许公共读,或 CDN 域名未绑定
Endpoint 错误填了带协议的地址,或区域不匹配
CDN 地址重复斜杠CDN 字段末尾加了 /

#11. DeepSeek / AI 分析配置

插件路径:

text
plugins/ai-analyzer/

后台入口:

模板插件 -> 插件中心 -> AI 网站分析

配置:

  • DeepSeek Key

保存后,站点新增/编辑页会在网址附近出现 AI 分析能力,自动生成:

  • 码力点评
  • 推荐理由
  • 适合人群
  • 优点
  • 缺点/注意

安全说明:

  • DeepSeek Key 后台不明文回显。
  • 保存时留空不会覆盖旧 Key。
  • 操作日志会过滤敏感字段。
  • JSON 备份导出会遮罩敏感值。

#12. 计划任务配置

当前推荐采用“统一任务中心 + 宝塔证书续签独立”的计划任务方案。

正式推荐配置:

  • app/cron/cron_worker.php:统一后台任务执行器,处理文章采集队列、导航采集流水线、素材修复队列、搜索推送、自发文章自动选题、点击量汇总和随机今日浏览量等站内任务。
  • 宝塔证书续签任务:保持宝塔独立任务,不合并到码力导航 worker。

不再建议独立配置:

  • app/cron/cron_collect.php:已由 app/cron/cron_worker.php 覆盖,仅作为兼容或手动排查脚本保留。
  • app/cron/cron_nav_discover.php:已由 app/cron/cron_worker.php 覆盖,仅作为兼容或手动排查脚本保留。
  • app/cron/cron_clicks.php:已由统一任务中心覆盖,仅作为兼容或手动排查脚本保留。
  • app/cron/cron_random_today.php:已由统一任务中心覆盖,仅作为兼容或手动排查脚本保留。

所有任务都建议在宝塔计划任务里用 Shell 脚本运行,不建议通过 URL 触发。

#12.1 查询 PHP CLI 路径

宝塔常见 PHP CLI 路径:

text
/www/server/php/74/bin/php
/www/server/php/80/bin/php
/www/server/php/81/bin/php

SSH 查询:

bash
which php
/www/server/php/74/bin/php -v

如果你的网站使用 PHP 7.4,计划任务也建议使用同版本:

bash
/www/server/php/74/bin/php

#12.2 统一任务中心

宝塔配置:

计划任务 -> 添加任务

  • 任务类型:Shell 脚本
  • 任务名称:码力导航任务中心集合
  • 执行周期:推荐每 1 到 5 分钟一次
  • 脚本内容:
bash
cd /www/wwwroot/www.example.com
/www/server/php/74/bin/php app/cron/cron_worker.php

带日志版本:

bash
cd /www/wwwroot/www.example.com
/www/server/php/74/bin/php app/cron/cron_worker.php >> /www/wwwlogs/malinav_worker.log 2>&1

作用:

  • 检查自动采集文章源,并将到期源加入文章采集任务队列。
  • 处理文章采集队列。
  • 执行导航发现、AI 补全和符合规则的候选入库。
  • 执行素材修复队列。
  • 执行搜索推送队列。
  • 执行自发文章自动选题。
  • 执行点击量汇总和随机今日浏览量等后台已启用任务。
  • 使用锁文件避免并发重复执行。

后台配置:

数据工具 -> 任务中心 -> 统一计划任务设置

  • 每个任务可单独开关。
  • 间隔分钟 仅对“间隔”任务生效。
  • 每日时间 仅对“每日”任务生效,格式 HH:MM
  • 单轮数量 控制每次最多处理多少条,0 表示使用程序默认值。
  • 数据字段 用于不同任务的细分配置,例如随机今日浏览量范围、导航发现/AI/入库数量。

#12.3 点击量汇总兼容脚本

脚本:

text
app/cron/cron_clicks.php

作用:

  • 汇总点击量。
  • 校准今日、月度、总点击数据。
  • 完成跨日重置。
  • 降低前台访问时数据库压力。

宝塔配置:

当前不建议再单独配置宝塔任务。需要排查时可手动执行:

bash
cd /www/wwwroot/www.example.com
/www/server/php/74/bin/php app/cron/cron_clicks.php

#12.4 推荐任务频率

任务推荐频率说明
app/cron/cron_worker.php每 1-5 分钟推荐常驻,统一处理站内后台任务
宝塔证书续签按宝塔默认保持独立,不合并
app/cron/cron_clicks.php手动排查兼容脚本,不建议单独常驻
app/cron/cron_random_today.php手动排查兼容脚本,不建议单独常驻

#12.5 手动测试计划任务

SSH 执行:

bash
cd /www/wwwroot/www.example.com
/www/server/php/74/bin/php app/cron/cron_worker.php

正常输出类似:

text
[2026-07-16 12:00:00] article tasks drained | nav: 发现新增 0 个;AI 补全 0 个;入库 0 个 | assets: done 0, failed 0

如果报数据库错误,优先检查 config/database.php

#12.6 不建议 URL 触发

cron 脚本默认禁止 Web 直接访问,避免被外部滥用。

不推荐这样访问:

text
https://www.example.com/app/cron/cron_worker.php

如果必须 URL 触发,代码里虽然支持 ?allow_web,但生产环境不建议使用。更安全的做法是只用宝塔 Shell 计划任务。


#13. 后台采集说明

#13.1 文章采集

后台入口:

采集设置 -> 文章采集

采集源字段包括:

  • 名称
  • 来源名
  • 类型:RSS / 列表页
  • RSS 地址
  • 列表选择器
  • 标题选择器
  • 链接选择器
  • 文章类型
  • 文章模式
  • 分类
  • 间隔/超时
  • 启用
  • 自动采集
  • 每次采集上限(1-100)
  • 增量游标(普通资讯源开启,会重新排序的榜单关闭)
  • 采集详情
  • 免审发布

如果启用自动采集,建议配置 app/cron/cron_worker.php。统一执行器会按采集源间隔自动创建任务,并继续处理待执行队列。

系统预置 GitHub 中文趋势日榜 源:列表地址为 https://trending.malinav.com/,列表项选择器为 article.repo-card,标题选择器为 span.collect-title,链接选择器为 a。标题格式为“项目名-中文 AI 简介第一句”,无 AI 简介时回退到项目描述。该源默认每 24 小时完整扫描一次、上限 50 条、仅保存标题与站内分析详情链接,文章模式为外链跳转且不免审发布。它由现有统一 worker 调度,不需要增加宝塔计划任务。

文章采集页面的批量操作说明:

  • “删除勾选”只删除当前勾选的采集结果,确认后提交到删除动作,不会执行文章导入。
  • “清除当前源任务”只清理当前采集源的任务记录。
  • “清除全部任务”使用 source_id=0 清理所有文章采集源的任务记录,并提示实际删除数量;该操作不会删除采集源配置。
  • 清除任务等写操作带 CSRF 校验。后台页面打开时间过长或登录会话失效时,应先刷新页面,再重新确认操作。

#13.2 导航采集

后台入口:

采集设置 -> 导航采集

主要用于从内置精品发现源、批量网址导入和 AI 补全流程中发现候选站点。

当前导航采集流程:

  • 发现源采集:内置国内/海外精品源,抓取候选站点。
  • 候选池去重:过滤社交链接、隐私条款、广告跳转、图片代理、GitHub 噪声等常见无效链接。
  • AI 补全:使用 DeepSeek 补全标题、简介、分类、标签、优缺点、评分等字段。
  • 精品入库:将符合质量要求的候选发布到站点库。

采集入库默认规则:

  • 统一四星。
  • 默认关闭图标显示。
  • 不自动进入推荐位。
  • 不自动进入精选位。
  • 不自动设置热门/加热。

如果不希望导航采集自动入库,需要调整 app/cron/cron_worker.phpcollect_auto_discover() 的入库阶段;不要再额外配置 app/cron/cron_nav_discover.php 计划任务。

#13.3 搜索推送

后台入口:系统设置 -> 搜索推送

主要能力:

  • 查看当前推送状态、待推送、成功、失败统计。
  • 一键开启/关闭 IndexNow。
  • 立即推送待队列链接。
  • 补推现有链接,把站内公开页面重新加入队列。
  • 打开主动提交插件入口。
  • 队列支持分页浏览。
  • 队列支持按全部、待推送、成功、失败筛选。
  • 队列支持选中记录后批量重试或删除。
  • 队列支持清空成功记录、清空失败记录。
  • 队列支持检查无效文章链接,将不公开的站内文章 URL 标记为失败并写入原因。

部署提示:

  • 现有链接补推是先入队,再由 app/cron/cron_worker.php 分批发送。
  • 如果站点长期没有跑过任务,建议先点补推,再让 app/cron/cron_worker.php 跑几轮。
  • 只需要保留 app/cron/cron_worker.php 常驻任务,不需要额外加独立的搜索推送计划任务。
  • IndexNow 入队会把相对路径规范为绝对 URL。
  • 普通文章只有在“已启用 + 站内文章 internal”时才会推送 /article/{id}.html
  • 外链文章、隐藏文章、草稿文章不会再作为公开文章页推送。
  • 推送前会二次校验站内文章是否仍公开,避免旧队列里残留无效文章 URL。

#13.4 采集安全建议

  • 不要关闭内网拦截。
  • 不要把采集超时设置过大。
  • RSS 源建议优先使用 HTTPS。
  • 免审发布只对可信源开启。
  • 采集异常可看 系统设置 -> 错误日志

#14. 素材队列说明

后台入口:

数据工具 -> 素材队列

作用:

  • 修复站点 favicon。
  • 修复 Logo。
  • 修复截图。
  • 将外链素材转为本地或 OSS。

素材队列可由后台手动运行,也可由 app/cron/cron_worker.php 自动处理:

  • 可以手动入队。
  • 可以执行下一批任务。
  • 可以开启后台页面里的自动执行器。
  • 统一任务中心每轮会处理少量素材任务。

不建议用系统 cron 直接调用内部队列接口;生产环境使用 app/cron/cron_worker.php 即可。


#15. 缓存、日志与备份

#15.0 远程图片代理缓存

程序提供 /image-proxy 路由,用于处理部分来源站点的图片防盗链问题。

当前用途:

  • IT之家图片域名 img.ithome.com 会限制 Referer,正文直接引用容易 403。
  • 程序只允许代理 img.ithome.com,不是开放代理。
  • 代理请求会带 Referer: https://www.ithome.com/
  • 图片缓存到 static/cache/remote_images
  • IT之家图片不上传 OSS。

注意:

  • 不要把 IT之家正文图改回裸链,否则前台仍可能出现 403。
  • static/cache/remote_images 需要可写。

#15.1 缓存目录

  • 超级管理员可通过后台顶部的橡皮擦图标清除前台缓存;该操作只删除 ml_cache_dir() 下的 .cache 文件,并写入后台操作日志。
  • 清理后前台页面会在下一次访问时自动重建缓存,不需要重启 PHP、Nginx 或数据库。
text
static/cache/

可能包含:

  • 首页缓存
  • 移动端缓存
  • sitemap 缓存

如果前台内容不刷新,可尝试清理该目录下缓存文件,但不要删除目录本身:

bash
rm -f static/cache/*.cache

#15.2 日志目录

text
static/logs/

后台也有:

系统设置 -> 操作日志

系统设置 -> 错误日志

建议定期清理旧日志。后台已经提供日志清理按钮。

#15.3 后台 JSON 备份

入口:

数据工具 -> 数据导出 -> 下载 JSON 备份

备份包含:

  • 站点
  • 文章
  • 分类
  • 工具
  • 页面
  • 广告
  • 设置摘要
  • 媒体引用

敏感字段会被遮罩,不会明文导出 OSS Secret、DeepSeek Key 等。

#15.4 宝塔备份建议

建议同时配置:

  • 网站文件备份:每天一次,保留 7 到 15 份。
  • 数据库备份:每天一次,保留 15 到 30 份。
  • 重要更新前手动备份一次。

迁移时至少需要:

  • 网站完整文件
  • 数据库 SQL
  • config/database.php 根据新服务器调整
  • OSS / DeepSeek 等密钥重新确认

#16. 上线安全清单

上线前请逐项确认:

  • 已开启 HTTPS。
  • 数据库账号不是 root,且密码足够复杂。
  • install.lock 存在。
  • install.php 如无必要,可改名或限制访问。
  • Nginx 已禁止访问 appconfigdatabase.codex
  • Nginx 已禁止访问 .sql.bak.log.env
  • static/cachestatic/logs 不允许公网直接访问。
  • 后台管理员密码足够复杂。
  • 宝塔面板开启安全入口和强密码。
  • 宝塔、SSH、数据库不对公网弱口令开放。
  • PHP 禁用危险函数时不要影响截图功能。
  • 计划任务使用 Shell,不通过 URL 公开触发。
  • OSS 使用 RAM 子账号,不使用主账号 Key。
  • DeepSeek Key 不写进文档、不写进前端。
  • 定期下载后台 JSON 备份。
  • 定期备份数据库。

#17. 宝塔 open_basedir 设置

宝塔默认可能开启防跨站攻击,也就是 open_basedir

通常保持开启即可,但如果遇到:

  • Chrome 截图无法读写临时目录
  • 计划任务路径异常
  • PHP 无法访问站点外日志目录

可以检查:

网站 -> 目标站点 -> 设置 -> 网站目录 -> 防跨站攻击(open_basedir)

如果关闭该项,需要更注意目录访问安全。推荐优先通过调整目录权限解决,而不是直接关闭。


#18. 故障排查

#18.0 文章采集清除或删除按钮无效

按以下顺序检查:

  1. 刷新文章采集页面后重新操作,排除登录会话或 CSRF 令牌过期。
  2. 检查浏览器确认框是否正常出现;取消确认不会提交删除。
  3. “清除全部任务”应提交 action=article_collect_tasks_clearsource_id=0;“删除勾选”应提交到采集结果删除动作,不能仍指向导入动作。
  4. 检查线上 app/AdminAuth.phpapp/admin/article_collect.php 是否同步为同一版本,并确认 PHP 语法检查通过。
  5. 操作完成后核对页面提示的实际删除数量,再检查任务或采集结果列表,不要仅凭按钮点击状态判断。

#18.1 首页 500 / 数据库连接失败

检查:

bash
cat config/database.php

确认数据库名、账号、密码、端口正确。

宝塔数据库里确认数据库存在。

#18.2 伪静态页面 404

例如:

text
/html/update.html
/article/420.html

如果 404,检查宝塔伪静态是否填入:

nginx
location / {
    try_files $uri $uri/ /index.php?$query_string;
}

#18.3 后台登录后空白

检查:

  • PHP 版本是否正确。
  • PHP 扩展是否安装。
  • static/cachestatic/logs 是否可写。
  • 宝塔错误日志。
  • 系统设置 -> 错误日志

#18.4 上传图片失败

检查:

  • fileinfo 扩展是否开启。
  • static/uploads/media 是否可写。
  • 上传文件是否超过 PHP 限制。
  • OSS 配置是否完整。
  • Bucket 是否允许写入和读取。

PHP 上传限制在宝塔:

软件商店 -> PHP -> 设置 -> 配置修改

关注:

  • upload_max_filesize
  • post_max_size
  • memory_limit
  • max_execution_time

#18.5 截图失败

依次检查:

  1. Chrome 是否安装:
bash
which google-chrome-stable
google-chrome-stable --version
  1. 后台是否填写 Chrome 路径。
  2. PHP 是否允许 proc_open
  3. static/uploads/screenshots 是否可写。
  4. 服务器是否能访问目标网址:
bash
curl -I https://target-site.com
  1. www 用户测试 Chrome。

#18.6 AI 分析失败

检查:

  • 插件中心是否配置 DeepSeek Key。
  • 服务器是否能访问 DeepSeek API。
  • Key 是否有效。
  • 余额是否充足。
  • 后台错误日志是否有 API 报错。

测试网络:

bash
curl -I https://api.deepseek.com

#18.7 计划任务不执行

检查:

  • 宝塔计划任务是否启用。
  • PHP CLI 路径是否正确。
  • 脚本是否使用绝对路径或已 cd 到站点目录。
  • 计划任务日志是否有数据库连接错误。
  • 脚本是否有执行权限不是关键,PHP 直接执行文件即可。

建议脚本内容总是写成:

bash
cd /www/wwwroot/www.example.com
/www/server/php/74/bin/php app/cron/cron_clicks.php

不要写成:

bash
php app/cron/cron_clicks.php

因为宝塔计划任务里的 php 可能不是网站所用 PHP 版本。


#19. 推荐上线流程

  1. 宝塔创建站点、数据库、SSL。
  2. 上传程序文件。
  3. 配置伪静态。
  4. 配置目录权限。
  5. 导入数据库或访问 install.php 安装。
  6. 登录后台。
  7. 打开 系统设置 -> 系统状态 检查环境。
  8. 配置站点基础信息。
  9. 安装并填写 Chrome 路径。
  10. 测试站点编辑页自动截图。
  11. 配置 OSS,并在媒体库上传小图测试。
  12. 配置 DeepSeek Key,并测试站点 AI 分析。
  13. 配置计划任务:只常驻 app/cron/cron_worker.php,建议每 1-5 分钟执行;宝塔证书续签保持独立。其他 app/cron/cron_*.php 脚本仅用于兼容或手动排查。
  14. 打开前台主要页面检查:
  15. - 首页 - 分类页 - 详情页 - 文章页 - 排行榜 - 最近更新 - 手机端页面

  16. 配置宝塔网站和数据库自动备份。
  17. 检查安全规则,确认敏感目录不可访问。

#20. 常用命令速查

进入站点目录:

bash
cd /www/wwwroot/www.example.com

检查 PHP:

bash
/www/server/php/74/bin/php -v

检查 PHP 扩展:

bash
/www/server/php/74/bin/php -m | egrep "pdo_mysql|curl|mbstring|fileinfo|gd|openssl|zip"

检查语法:

bash
/www/server/php/74/bin/php -l index.php
/www/server/php/74/bin/php -l admin.php
/www/server/php/74/bin/php -l app/cron/cron_worker.php
/www/server/php/74/bin/php -l app/cron/cron_clicks.php
/www/server/php/74/bin/php -l app/cron/cron_random_today.php

执行统一任务中心:

bash
cd /www/wwwroot/www.example.com
/www/server/php/74/bin/php app/cron/cron_worker.php

执行点击汇总:

bash
cd /www/wwwroot/www.example.com
/www/server/php/74/bin/php app/cron/cron_clicks.php

执行随机今日浏览量:

bash
cd /www/wwwroot/www.example.com
/www/server/php/74/bin/php app/cron/cron_random_today.php

修复权限:

bash
cd /www/wwwroot/www.example.com
chown -R www:www .
chmod -R 755 static/uploads static/cache static/logs

检查 Chrome:

bash
which google-chrome-stable
google-chrome-stable --version

测试截图:

bash
sudo -u www /usr/bin/google-chrome-stable --headless=new --no-sandbox --disable-gpu --disable-dev-shm-usage --window-size=800,600 --screenshot=/tmp/malinav-test.png https://www.example.com
ls -lh /tmp/malinav-test.png

#21. 备注

  • 本程序的采集、截图、AI 分析都依赖服务器主动访问外部网站或 API。服务器安全组、防火墙、DNS、运营商出口都会影响这些功能。
  • 后台密钥表单通常采用“已保存,留空不修改”的策略,这是正常现象。
  • 备份导出的 JSON 会遮罩敏感值,不能作为完整密钥迁移文件。迁移后请重新确认 OSS 和 DeepSeek Key。
  • 生产环境建议保留 install.lock,并通过 Nginx 阻止访问敏感目录和敏感文件。
  • 如果遇到难以定位的问题,优先查看:宝塔站点错误日志、PHP 错误日志、后台错误日志、计划任务执行日志。