PHP Server Monitor 3.5.2 Docker Compose 部署指南

在真实 Linux 服务器上以 Docker Compose 部署 PHP Server Monitor 3.5.2:官方镜像仓库自构建、MariaDB 数据持久化、安装向导与 HTTP/TCP 监控项实测,含 bullseye 构建排障与 7 条常见问题。

PHP Server MonitorDocker Compose自托管监控PHP 应用2026/11/01

PHP Server Monitor 3.5.2 Docker Compose 部署指南

目标:在一台 Linux 服务器上用 Docker Compose 完整跑起 PHP Server Monitor 3.5.2(网站/服务器可用性监控,PHP + MariaDB),包括镜像构建、安装向导、HTTP 与 TCP 端口监控项配置和检测落库验证。本文全部命令与回显已在 Ubuntu 26.04.1 LTS(x86_64,Docker 29.9.2 / Compose v5.6.1,16GB 内存)真实服务器上实测通过。

一、环境信息

  • 操作系统:Ubuntu 26.04.1 LTS(x86_64)
  • Docker:29.9.2;Docker Compose:v5.6.1(plugin 形态)
  • PHP Server Monitor:3.5.2(官方 Dockerfile 自构建镜像 phpservermonitor:3.5.2,实测体积 787MB)
  • 数据库:MariaDB 10.6 官方镜像(实测版本 10.6.28)
  • 部署目录:/opt/data/quzuo/tmp/php-server-monitor/stack(下文所有相对路径基于此目录)
  • 服务端口:8138(映射到容器内 Apache 的 80)
  • 容器:phpservermon-3.5.2-web(PHP + Apache + PSM)、phpservermon-3.5.2-db(MariaDB)
  • 容器网络:自定义 bridge 网络,子网 10.89.66.0/24(部署前已用 docker network ls 确认 10.89.56–65 段被其他项目占用,故取 66 段)
  • Compose 项目名:php-server-monitor-3.5.2-stack(由 compose 文件顶层 name: 显式指定)

二、镜像选型说明

2.1 官方安装路径与镜像现状

PHP Server Monitor 的官方主路径是 PHP 源码 + LAMP(下载 tar.gz 解压到 Web 目录,走浏览器安装向导,详见官方文档 docs.phpservermonitor.org 的 install 篇)。在 Docker 这条线上,官方姿态如下(2026-11-01 实查):

  • GitHub 组织下有官方镜像仓库 phpservermon/docker-phpservermonitor:提供 Dockerfile、docker-entrypoint.sh、maria-wait.sh,不发布到 Docker Hub,需要自行构建;Dockerfile 固定 VERSION 3.5.2,基础镜像 php:7.4-apache,并内置"每 N 秒跑一次检测 cron"的后台循环与等库启动脚本。
  • Docker Hub 上的 phpservermon/phpservermon 是一个空壳仓库(无有效分层、无可 pull 的标签,2016 年后无活动)。
  • 第三方镜像 benoitpodwinski/phpservermon 累计 pulls 较多(约 67.9 万),但镜像停在 2020-11,其后无更新。

2.2 本文选型与取舍

💡 技术拓展:PSM 这类"PHP 源码 + Web 安装向导"的传统 PHP 应用,容器化常见三种做法——①官方 Dockerfile 自构建;②第三方镜像直接 pull;③自己写 Dockerfile 把源码塞进 php:7.4-apache。三者差异:①最忠实官方(入口脚本、cron 循环、会话目录都已处理),但要自己 build;②开箱即用,但版本与维护状态看运气;③最灵活,成本最高。

本文选择 ①官方 docker-phpservermonitor 仓库自构建:

  • 与 3.5.2 源码严格对应(Dockerfile 构建时直接从 GitHub 拉 v3.5.2.tar.gz);
  • 官方入口脚本解决了 PSM 容器化最大的两件麻烦事:config.php 自动生成(PSM_AUTO_CONFIGURE=true)、数据库就绪等待(maria-wait.sh);
  • 内置检测循环(PSM_REFRESH_RATE_SECONDS),容器起来即自动开始监控,无需宿主机 crontab。

代价是构建期需要外网(Debian 归档源、getcomposer.org、GitHub),且 Debian 11 bullseye 已归档需要打一个源地址补丁(见四、4.2,踩坑实录)。

三、前置条件

  • 服务器已安装 Docker 24+ 与 Compose v2+ 插件(本文实测环境为 Docker 29.9.2 + Compose v5.6.1);
  • 2GB 以上空闲内存、3GB 以上磁盘(镜像 787MB + MariaDB 数据);
  • 构建期可访问外网:archive.debian.org(Debian 归档源)、getcomposer.org(Composer 安装器)、github.com(源码包);
  • 规划端口:本文使用 8138,部署前确认未被占用:ss -lntp | grep 8138 无输出即可;
  • 规划容器网络子网:先 docker network ls + docker network inspect 确认 10.89.0.0/16 内空闲段,本文取 10.89.66.0/24;
  • 如需从 Docker Hub 拉取 mariadb:10.6 基础镜像失败,可按所在网络配置代理(本文环境通过 192.168.1.72:7897 代理完成 pull)。

四、部署步骤

4.1 准备部署目录与官方镜像源码

mkdir -p /opt/data/quzuo/tmp/php-server-monitor/stack   # 部署目录
cd /opt/data/quzuo/tmp/php-server-monitor/stack
git clone https://github.com/phpservermon/docker-phpservermonitor.git   # 官方镜像仓库(含 Dockerfile/entrypoint/maria-wait)

4.2 构建镜像(含 bullseye 归档源补丁)

直接 docker compose build 会在 apt-get update / 安装阶段报 404——基础镜像 php:7.4-apache 基于 Debian 11 (bullseye),deb.debian.org 已把 bullseye-security 的旧版本包下线(libcap2、libcurl4 等)。修复办法是把源切到 archive.debian.org 并跳过过期检查。在 docker-phpservermonitor/Dockerfile 的 FROM php:7.4-apache 之后插入:

# Debian 11 (bullseye) 已归档:deb.debian.org 的 bullseye-security 旧版本包 404,切换 archive.debian.org
RUN sed -i 's|http://deb.debian.org/debian-security|http://archive.debian.org/debian-security|g; s|http://deb.debian.org/debian|http://archive.debian.org/debian|g' /etc/apt/sources.list \
    && apt-get update -o Acquire::Check-Valid-Until=false

⚠️ 注意:这一步是本文实测中唯一的"必须补丁",其余 Dockerfile 内容保持官方原样即可。补丁位置必须在首个 apt-get 之前。

执行构建(首次构建各步骤真实执行,耗时数分钟;本文环境二次构建全部命中缓存):

cd /opt/data/quzuo/tmp/php-server-monitor/stack
docker compose build   # 实测回显(缓存命中形态,节选)
#14 CACHED

#15 [ 2/14] RUN sed -i 's|http://deb.debian.org/debian-security|http://archive.debian.org/debian-security|g; s|http://deb.debian.org/debian|http://archive.debian.org/debian|g' /etc/apt/sources.list     && apt-get update -o Acquire::Check-Valid-Until=false
#15 CACHED

#16 [ 7/14] RUN sed -i 's/;date.timezone =/date.timezone = "${PHP_TIME_ZONE}"/g' "/usr/local/etc/php/php.ini"
#16 CACHED
...
#20 exporting to image
#20 exporting layers done
#20 naming to docker.io/library/phpservermonitor:3.5.2 done
#20 unpacking to docker.io/library/phpservermonitor:3.5.2 done
#20 DONE 0.1s
 Image phpservermonitor:3.5.2 Built

确认镜像:

docker images phpservermonitor:3.5.2
IMAGE                    ID             DISK USAGE   CONTENT SIZE   EXTRA
phpservermonitor:3.5.2   e09e9610b004        787MB          205MB   U

4.3 编写 docker-compose.yml(全文)

在部署目录创建 docker-compose.yml,以下为本文实测使用的全文:

name: php-server-monitor-3.5.2-stack

services:
  phpservermonitor:
    build: ./docker-phpservermonitor
    image: phpservermonitor:3.5.2
    container_name: phpservermon-3.5.2-web
    restart: unless-stopped
    environment:
      - PHP_TIME_ZONE=Asia/Shanghai
      - PSM_REFRESH_RATE_SECONDS=60
      - PSM_AUTO_CONFIGURE=true
      - PSM_PHP_DEBUG=false
      - MYSQL_HOST=db
      - MYSQL_USER=phpservermonitor
      - MYSQL_PASSWORD=q1w2e3r4
      - MYSQL_DATABASE=phpservermonitor
      - MYSQL_DATABASE_PREFIX=psm_
    ports:
      - "8138:80"
    volumes:
      - ./sessions:/sessions
    depends_on:
      - db
    networks:
      - psm-net

  db:
    image: mariadb:10.6
    container_name: phpservermon-3.5.2-db
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=q1w2e3r4
      - MYSQL_USER=phpservermonitor
      - MYSQL_PASSWORD=q1w2e3r4
      - MYSQL_DATABASE=phpservermonitor
    volumes:
      - ./mariadb:/var/lib/mysql
    networks:
      - psm-net

networks:
  psm-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.66.0/24

要点:

  • name: php-server-monitor-3.5.2-stack 显式指定项目名,容器名固定为 phpservermon-3.5.2-web / phpservermon-3.5.2-db,避免目录名漂移;
  • 数据库连通参数(MYSQL_HOST=db 指向 compose 服务名)只用于自动生成 config.php,见七、;
  • ./sessions:/sessions 挂载 PHP 会话目录(镜像内 session.save_path=/sessions),属主必须正确,否则安装向导会报 401(见十一、11.3);
  • ./mariadb:/var/lib/mysql 把数据库落盘到部署目录,容器删除数据不丢;
  • 子网显式声明,避免与其他 compose 项目自动分配的网段冲突。

4.4 启动服务栈

cd /opt/data/quzuo/tmp/php-server-monitor/stack
docker compose up -d

实测回显(Compose 会把项目名中的小数点剔除,实际网络名为 php-server-monitor-352-stack_psm-net,见下方说明):

 Network php-server-monitor-352-stack_psm-net Creating
 Network php-server-monitor-352-stack_psm-net Created
 Container phpservermon-3.5.2-db Creating
 Container phpservermon-3.5.2-db Created
 Container phpservermon-3.5.2-web Creating
 Container phpservermon-3.5.2-web Created
 Container phpservermon-3.5.2-db Starting
 Container phpservermon-3.5.2-db Started
 Container phpservermon-3.5.2-web Starting
 Container phpservermon-3.5.2-web Started

💡 说明:Compose 会把项目名中的小数点剔除,php-server-monitor-3.5.2-stack 项目对应的实际网络名是 php-server-monitor-352-stack_psm-net(docker network ls 实测),九、的等价 docker run 命令要用这个实际网络名。

查看状态与启动日志:

docker compose ps --format 'table {{.Name}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
NAME                     IMAGE                    STATUS          PORTS
phpservermon-3.5.2-db    mariadb:10.6             Up 27 minutes   3306/tcp
phpservermon-3.5.2-web   phpservermonitor:3.5.2   Up 31 seconds   0.0.0.0:8138->80/tcp, [::]:8138->80/tcp
docker logs phpservermon-3.5.2-web 2>&1 | grep -v '^\[' | head -8
Auto Configure / Create config.php
Waiting until database is ready...
Waiting until MariaDB has started
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.89.66.3. Set the 'ServerName' directive globally to suppress this message

日志三段含义:①入口脚本按 PSM_AUTO_CONFIGURE=true 自动生成 config.php;②maria-wait.sh 轮询 db:3306 直到数据库就绪;③启动 Apache(AH00558 只是 ServerName 提示,可忽略)。同时入口脚本在后台启动了检测循环(每 PSM_REFRESH_RATE_SECONDS=60 秒执行一次 php cron/status.cron.php)。

4.5 安装向导实测(数据库连接与管理员账号)

浏览器访问 http://<服务器IP>:8138/,PSM 在未安装状态下会自动进入安装向导(安装完成后向导不再可用,实测再访问 /install/ 路径返回 Apache 404,因为该物理路径并不存在,向导由应用路由在"数据库无版本号"时自动启用)。

实测安装流程与页面关键内容:

  1. 欢迎页:环境自检通过,显示 PHP version: 7.4.33、PHP cURL module found;

  2. 数据库配置页:由于 compose 已注入 MYSQL_* 环境变量且 PSM_AUTO_CONFIGURE=true 生成了 config.php,数据库连接参数已自动预填(host=db、库名 phpservermonitor、用户 phpservermonitor、表前缀 psm_),页面连接测试通过,实测提示语:

    Sweet, your database connection is up and running!
    
  3. 创建管理员:填入用户名 admin、密码 q1w2e3r4、邮箱 admin@example.com,提交后建表成功;

  4. 建表结果(SHOW TABLES 实测,共 9 张):

    psm_config
    psm_log
    psm_log_users
    psm_servers
    psm_servers_history
    psm_servers_uptime
    psm_users
    psm_users_preferences
    psm_users_servers
    
  5. 登录:用 admin / q1w2e3r4 登录,进入 SERVER MONITOR - Status 页面,右上角显示 Welcome, admin。PSM 预置了 2 个示例监控项(SourceForge、Gmail SMTP,见 4.6)。

4.6 添加监控项实测(HTTP 检测与 TCP 端口检测)

在 Web 界面 Servers → Add new server 添加两个监控项(演示值即实测值):

  • HTTP 检测(类型 Website):https://www.quzuo.net。保存时 PSM 自动从 URL 提取端口 443(https 默认 443,http 默认 80),无需手填;
  • TCP 端口检测(类型 Service):目标填容器网络内主机名 db、端口 3306,即监控 MariaDB 自身。

保存后查看数据库中的监控项清单:

docker exec phpservermon-3.5.2-db mariadb -uphpservermonitor -pq1w2e3r4 phpservermonitor \
  -e "SELECT server_id,label,type,ip,port,active,timeout FROM psm_servers;"
server_id  label           type      ip                                port  active  timeout
1          SourceForge     website   http://sourceforge.net/index.php  80    yes     NULL
2          Gmail SMTP      service   smtp.gmail.com                    465   yes     NULL
3          本地 MySQL 端口   service   db                                3306  yes     10
4          Quzuo 官网首页   website   https://www.quzuo.net             443   yes     10

💡 技术拓展:PSM 的三种检测类型语义容易望文生义,以源码 src/psm/Util/Server/Updater/StatusUpdater.php 为准——ping=执行系统 ping/ping6 命令(ICMP);service=fsockopen 建立 TCP 连接(测端口通断);website=curl 发 HTTP 请求看状态码/响应头。TCP 端口检测要选 Service 而不是 Ping。且 Service/Ping 类型的目标框只接受 IP 或纯域名(填 http:// 开头的 URL 保存会报 "The IP address is not valid.",见十一、11.5)。

4.7 检测执行与结果落库验证

容器内置循环每 60 秒跑一轮检测(含预置示例项)。等一两分钟后查库验证:

docker exec phpservermon-3.5.2-db mariadb -uphpservermonitor -pq1w2e3r4 phpservermonitor \
  -e "SELECT server_id,label,type,ip,port,status,ROUND(rtime,3) AS rtime,last_check,last_online FROM psm_servers;"
server_id  label           type      ip                                port  status  rtime   last_check           last_online
1          SourceForge     website   http://sourceforge.net/index.php  80    off     0.563   2026-11-01 11:59:48  NULL
2          Gmail SMTP      service   smtp.gmail.com                    465   off     10.016  2026-11-01 12:00:08  2026-11-01 11:53:22
3          本地 MySQL 端口   service   db                                3306  on      0.000   2026-11-01 12:00:08  2026-11-01 12:00:08
4          Quzuo 官网首页   website   https://www.quzuo.net             443   on      0.097   2026-11-01 12:00:08  2026-11-01 12:00:08

结果解读:

  • db:3306、https://www.quzuo.net 两个新加项 status=on,响应时间 rtime 分别为 0.000s(本机 TCP)与 0.097s(HTTPS);
  • 预置示例 SourceForge 显示 off:本环境实测其响应头为 HTTP/1.1 403 Forbidden(Cloudflare 拦截),PSM 只认 2xx,属环境现象不是故障(见十一、11.6);
  • 每轮检测还会写入 psm_servers_uptime 历史表(实测 4 个监控项分别已有 8/8/4/4 行记录),供后续可用率报表使用。

五、数据持久化说明

持久化对象挂载/位置实测情况说明
MariaDB 数据./mariadb → /var/lib/mysql149MB(9 张表 + 检测历史)PSM 的全部业务数据(监控项、用户、配置、历史)都在库里,这是唯一需要认真备份的状态
PHP 会话./sessions → /sessions60KB登录态/CSRF 依赖会话文件;目录属主必须是 www-data(uid 33),见 11.3
config.php容器内 /var/www/html/config.php不持久化PSM_AUTO_CONFIGURE=true 时每次容器启动由入口脚本按 MYSQL_* 环境变量重新生成,无需挂载保存

⚠️ 注意:升级镜像(换新版本重建容器)不会丢数据——数据库在宿主目录里,config.php 会重新生成。但 psm_config 表中的界面配置(语言、通知渠道、SMTP 等)随库走,所以备份 MariaDB 目录或 mariadb-dump(见十、10.2)即可完整保住一切。

六、环境变量表

Web 服务(phpservermonitor)使用的环境变量(默认值来自官方 Dockerfile):

环境变量镜像默认值本文取值作用说明
MYSQL_HOSTdatabasedb数据库主机名,compose 里就是 db 服务名
MYSQL_USERphpservermonitorphpservermonitor数据库用户
MYSQL_PASSWORDYOUR_PASSWORDq1w2e3r4数据库密码
MYSQL_DATABASEphpservermonitorphpservermonitor数据库名
MYSQL_DATABASE_PREFIXpsm_psm_表前缀,全部 9 张表以此为前缀
PHP_TIME_ZONEEurope/AmsterdamAsia/ShanghaiPHP 时区。镜像构建时把 date.timezone = "${PHP_TIME_ZONE}" 写入 php.ini,运行时由 PHP 展开 ${PHP_TIME_ZONE} 环境变量生效——本文实测容器内 ini_get('date.timezone') 返回 Asia/Shanghai,date() 输出与宿主 CST 一致
PSM_REFRESH_RATE_SECONDS9060容器内置检测循环的间隔(秒),每间隔执行一次 php cron/status.cron.php
PSM_AUTO_CONFIGUREtruetruetrue=启动时按 MYSQL_* 自动生成 config.php;false=改为预填安装向导默认值(sed 改 InstallController 源码)
PSM_PHP_DEBUGfalsefalsetrue 时生成 phpinfo.php 调试页,生产保持关闭
APACHE_DOCUMENT_ROOT/var/www/html未修改镜像内部变量,一般不动

数据库服务(db)使用 MariaDB 官方镜像的标准变量:MYSQL_ROOT_PASSWORD、MYSQL_USER、MYSQL_PASSWORD、MYSQL_DATABASE(本文均见四、4.3 compose 全文)。

七、配置参数说明

容器化部署下 PSM 的配置分三层:

  1. config.php(容器内自动生成)——仅数据库连接六要素。实测内容:

    docker exec phpservermon-3.5.2-web cat /var/www/html/config.php
    
    <?php
    define('PSM_DB_HOST', 'db');
    define('PSM_DB_PORT', '');
    define('PSM_DB_USER', 'phpservermonitor');
    define('PSM_DB_PASS', 'q1w2e3r4');
    define('PSM_DB_NAME', 'phpservermonitor');
    define('PSM_DB_PREFIX', 'psm_');
    ?>
    

    💡 说明:PSM_DB_PORT 为空是官方入口脚本的固定行为(define('PSM_DB_PORT', '')),PSM 会使用 MariaDB 默认端口 3306,连接正常,无需手工补。

  2. Web 配置界面(Config 模块)——语言、邮件/SMS/Pushover/Telegram/Jabber 通知、代理、日志保留期等日常配置,保存在 psm_config 键值表(实测键包括 language=en_US、email_status=1、log_retention_period=365、alert_type=status 等);

  3. 每监控项参数——超时、告警阈值(warning_threshold)、SSL 证书到期提醒天数等,随 psm_servers 表行存储。

三层的完整参数字典(config.php 全部 define、psmconfig.inc.php 常量、psm_config 表键)见本专栏《PHP Server Monitor 3.5.2 配置参数详解》。

八、配置文件挂载

默认模式下不需要挂载任何 PHP 配置文件:

  • config.php 由入口脚本每次启动自动生成,源头是 compose 的 MYSQL_* 环境变量;
  • php.ini 时区由 PHP_TIME_ZONE 环境变量控制(见六、);
  • 会话目录已单独挂载(./sessions:/sessions)。

如需手工管理 config.php(例如想加 PSM_BASE_URL、PSM_WEBCRON_KEY 等 define):

  1. compose 中设 PSM_AUTO_CONFIGURE=false(否则每次启动会被覆盖);

  2. 挂载配置文件:

    volumes:
      - ./config.php:/var/www/html/config.php:ro
    
  3. 保持文件对 Apache 运行用户(www-data)可读。

九、等价 docker run

与上述 compose 完全等价的纯 docker run 方式(本文实测通过:容器启动后 curl 返回 HTTP 200,登录页正常)。注意网络名用 compose 实际创建的 php-server-monitor-352-stack_psm-net(本文的 docker run 实测即接入 compose 已建网络;若想从零新建同名网络,需在 compose 网络不存在时执行 docker network create --subnet 10.89.66.0/24 php-server-monitor-352-stack_psm-net——当该子网已被 compose 网络占用时,实测会报 Error response from daemon: invalid pool request: Pool overlaps with other one on this address space,换空闲子网或直接复用现有网络即可):

# 数据库(若 compose 的 db 容器已在跑则跳过本步)
docker run -d --name phpservermon-3.5.2-db \
  --restart unless-stopped \
  --network php-server-monitor-352-stack_psm-net \
  -e MYSQL_ROOT_PASSWORD=q1w2e3r4 \
  -e MYSQL_USER=phpservermonitor \
  -e MYSQL_PASSWORD=q1w2e3r4 \
  -e MYSQL_DATABASE=phpservermonitor \
  -v /opt/data/quzuo/tmp/php-server-monitor/stack/mariadb:/var/lib/mysql \
  mariadb:10.6

# PSM Web
docker run -d --name phpservermon-3.5.2-web \
  --restart unless-stopped \
  --network php-server-monitor-352-stack_psm-net \
  -p 8138:80 \
  -e PHP_TIME_ZONE=Asia/Shanghai \
  -e PSM_REFRESH_RATE_SECONDS=60 \
  -e PSM_AUTO_CONFIGURE=true \
  -e PSM_PHP_DEBUG=false \
  -e MYSQL_HOST=db \
  -e MYSQL_USER=phpservermonitor \
  -e MYSQL_PASSWORD=q1w2e3r4 \
  -e MYSQL_DATABASE=phpservermonitor \
  -e MYSQL_DATABASE_PREFIX=psm_ \
  -v /opt/data/quzuo/tmp/php-server-monitor/stack/sessions:/sessions \
  phpservermonitor:3.5.2

实测验证(docker run 版容器启动后):

curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://127.0.0.1:8138/
HTTP 200

验证完切换回 compose 管理时:docker rm -f phpservermon-3.5.2-web 再 docker compose start phpservermonitor 即可(本文即如此实测恢复,回显 HTTP 200)。

十、常用运维命令

10.1 日常启停与日志

cd /opt/data/quzuo/tmp/php-server-monitor/stack
docker compose ps                      # 状态
docker compose logs -f phpservermonitor  # 跟踪 Web 容器日志(含每轮检测的告警尝试)
docker compose restart phpservermonitor  # 重启 Web
docker compose down                    # 停止并删容器(数据在 ./mariadb,不受影响)
docker compose up -d                   # 重新拉起

10.2 数据库备份与恢复(实测)

docker exec phpservermon-3.5.2-db mariadb-dump -uphpservermonitor -pq1w2e3r4 phpservermonitor > psm-backup-$(date +%F).sql

实测输出文件头部:

/*M!999999\- enable the sandbox mode */
-- MariaDB dump 10.19  Distrib 10.6.28-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost    Database: phpservermonitor

恢复(库损坏或迁移时,实测:将上述备份导回后无报错,SELECT COUNT(*) FROM psm_servers 返回 4,Web 页面 HTTP 200 正常):

docker exec -i phpservermon-3.5.2-db mariadb -uphpservermonitor -pq1w2e3r4 phpservermonitor < psm-backup-2026-11-01.sql

10.3 升级与重建

3.x 线当前最新稳定版为 3.5.2(2026-11-01 实查 GitHub Releases)。将来发布新版后:

  1. 修改 docker-phpservermonitor/Dockerfile 中的 ENV VERSION 3.5.2 为新版本号(同时 compose 中 image: 标签同步改);
  2. docker compose build && docker compose up -d;
  3. 数据库结构变更由 PSM 自带的版本升级逻辑在首次访问时处理(psm_config 表的 version 键记录当前版本,实测值为 3.5.2)。

十一、常见问题(FAQ)

Q1:docker compose build 在 apt 阶段大量 404(libcap2、libcurl4 等包)?

基础镜像 php:7.4-apache 是 Debian 11 (bullseye),其 bullseye-security 历史包已从 deb.debian.org 下线。按四、4.2 在 Dockerfile 里把源切到 archive.debian.org 并加 -o Acquire::Check-Valid-Until=false,实测一次通过。

Q2:容器反复重启,日志报 exec: "/usr/local/bin/maria-wait.sh": permission denied(退出码 126)?

官方仓库里 maria-wait.sh 以 git 的 100755 权限(可执行位)分发;若你用 curl/浏览器下载或复制该文件,执行位会丢,容器 ENTRYPOINT 执行它就会 126。修复:chmod +x docker-phpservermonitor/maria-wait.sh docker-phpservermonitor/docker-entrypoint.sh 后重新 docker compose build(BuildKit 的 COPY 层缓存按文件内容判断,改权限后需确认该层真的重建了)。本文实测打上执行位后一次启动成功。

Q3:安装向导点 Next、登录都返回 401 Unauthorized?

实测根因是 ./sessions 目录属主问题:宿主上以 root 新建的目录被挂进容器后覆盖了镜像内 www-data 属主的 /sessions,PHP 会话文件写不进去,表单 CSRF 令牌(存在会话里)每次请求都丢失,服务端 HMAC 校验失败直接 401。修复并实测通过:

chown -R 33:33 /opt/data/quzuo/tmp/php-server-monitor/stack/sessions   # 33 = www-data

Q4:容器日志出现 sh: 1: /usr/sbin/sendmail: not found,监控项掉线也没收到邮件?

镜像里没有 MTA,而 PSM 默认邮件通知走 PHP mail()(psm_config 表实测 email_status=1)。两个选择:①在 Config → Email Settings 里把发送方式改为 SMTP 并填 SMTP 服务器(走 PHPMailer);②容器内装 MTA(不推荐)。本文实测:仅记录日志、不中断检测循环。

Q5:保存 Service 类型监控项时报 The IP address is not valid.?

Service/Ping 类型的目标框只接受 IP 或纯域名(源码 ServerValidator.php 用正则强校验,不允许 scheme)。把 https://example.com 填进 Service 类型就会报这个错——URL 请用 Website 类型(保存时会自动补 http:// 并提取端口)。

Q6:预置的 SourceForge / Gmail SMTP 示例监控项一直是 offline?

本文实测环境里:SourceForge 返回 HTTP/1.1 403 Forbidden(Cloudflare 拦截该 PHP-cURL 指纹的直连请求,last_error_output 存有完整响应头),Gmail SMTP 的 465 端口出网 10 秒超时。两项都是示例数据,网络环境不可达即显示 offline,不影响其他监控项,不需要可删除。

Q7:改了 PSM_REFRESH_RATE_SECONDS 不生效?

该变量决定的是容器入口脚本里内置检测循环的 sleep 间隔,改完需要 docker compose up -d 重建容器才生效(docker compose restart 不重读环境变量)。另外它与数据库锁配合:若上一轮检测还没跑完(或被外部 crontab 同时触发),新一轮会直接打印 Cron is already running. Exiting. 退出,详见本专栏《PHP Server Monitor 3.5.2 常用 CLI 命令与 cron 托管详解》。

十二、参考链接