Skip to content

EduSoho PHP 安全升级指南(本地部署自运维客户 · 公众版 2026-10-22) ​

适用对象:本地部署、自行运维服务器的 EduSoho 客户。 目标:把服务器上的 PHP 升级到已包含本次安全修复的版本。

⚠️ 暂时无法立即升级的,请先按「临时缓解」一节处理,尽快止血,再安排正式升级。


0. 先确认你属于哪种情况 ​

部署方式服务器系统推荐做法章节
直接部署(apt 安装的 PHP)Ubuntu 22.04 / 24.04用 Ondřej Surý PPA 原地升级当前 PHP 版本§2
直接部署Ubuntu 22.04 以下、CentOS 等其他系统改用 Docker 运行 PHP-FPM§3
宝塔面板部署任意按宝塔专项说明处理§4
已经是 Docker 部署任意重建 PHP 镜像§5

同时请确认产品版本,决定是否顺带升级 PHP 大版本(见 §6):

产品可支持的最高 PHP 版本
教培版升级到 8.6.14 后支持 PHP 7.4
企培版升级到 24.2.6 后支持 PHP 8.3

查看当前 PHP 版本:

bash
php -v
php-fpm7.2 -v   # 或对应版本号的 php-fpmX.Y

临时缓解(升级前先做) ​

正式升级需要备份、测试、安排停机窗口,往往不能当天完成。在升级完成之前,请先按以下文章做临时缓解,降低被利用的风险:

👉 https://mp.weixin.qq.com/s/Gpt2ouEwYiYjeQMmELvcTw

注意:

  • 临时缓解不能代替升级,只是争取时间。完成缓解后,请尽快按下文完成正式升级。
  • 所有部署方式(直接部署、Docker、宝塔)都适用,修改配置前先备份相关文件。
  • 缓解措施生效后,请访问网站确认前后台功能正常。

1. 升级前准备(所有情况都必须做) ​

bash
# 1) 备份数据库
mysqldump -u root -p --single-transaction --routines edusoho > ~/edusoho-$(date +%F).sql

# 2) 备份代码与上传文件(按实际路径)
sudo tar czf ~/edusoho-code-$(date +%F).tgz /var/www/edusoho

# 3) 备份 PHP / Nginx 配置
sudo tar czf ~/php-nginx-conf-$(date +%F).tgz /etc/php /etc/nginx

# 4) 备份现有定时任务
sudo crontab -u www-data -l > ~/crontab-www-data.bak 2>/dev/null
sudo crontab -l > ~/crontab-root.bak 2>/dev/null

建议在业务低峰期操作,并提前通知学员/员工。


2. Ubuntu 22.04 / 24.04:PPA 原地升级 ​

Ubuntu 22.04 自带 PHP 8.1、24.04 自带 PHP 8.3,如果你的服务器上是 PHP 7.x,基本可以确定当初就是从 Ondřej Surý PPA 安装的。Ondřej Surý PPA 中有 PHP 7.x 系列的安全修复包。原来装的是哪个版本就升级哪个版本,例如原来是 PHP 7.1,就更新到 PHP 7.1.x 最新包。

以 PHP 7.2 为例(其他版本把 7.2 换成实际版本号):

bash
sudo add-apt-repository -y ppa:ondrej/php   # 已添加过可跳过
sudo apt-get update
sudo apt-get install --only-upgrade 'php7.2*'
sudo systemctl restart php7.2-fpm

国内服务器访问 Launchpad 可能较慢或超时,必要时请配置代理后再执行。

升级后按 §7 验证。


3. Ubuntu 22.04 以下 / 其他系统:Docker 运行 PHP-FPM ​

旧系统已无法获得安全更新,推荐用 Docker 运行 PHP-FPM,推荐 PHP 7.2(若已按 §6 升级产品版本,可相应改为 7.4 / 8.3,下文所有 7.2 同步替换)。

思路:新 PHP-FPM 跑在容器里,监听 127.0.0.1:9072;原 PHP-FPM 先不动,Nginx 切换过去验证正常后再停掉旧的,随时可回滚。

前提:已安装 Docker 及 docker compose 插件。较老的系统(如 Ubuntu 16.04/18.04、CentOS 7)可能装不上新版 compose 插件,可使用独立的 docker-compose 命令,下文 docker compose 换成 docker-compose 即可。

3.1 准备目录 ​

bash
sudo mkdir -p /opt/php-7.2
sudo chown -R $(whoami):$(id -gn) /opt/php-7.2
cd /opt/php-7.2
mkdir -p conf log data/cron

3.2 创建入口脚本 docker-php-entrypoint ​

在 /opt/php-7.2/ 下创建该文件(Dockerfile 会把它复制进镜像)。它负责准备运行目录、修正 crontab 权限、启动 cron,再拉起 php-fpm:

sh
#!/bin/sh
set -e

# php-fpm 的 pid 文件目录,容器里默认不存在,缺失会导致 php-fpm 启动失败
mkdir -p /run/php

# cron 目录挂载自宿主机,首次为空,需按 cron 要求的属主/权限初始化
mkdir -p /var/spool/cron/crontabs
chown root:crontab /var/spool/cron/crontabs
chmod 1730 /var/spool/cron/crontabs
for f in /var/spool/cron/crontabs/*; do
  [ -f "$f" ] || continue
  chown "$(basename "$f")":crontab "$f"
  chmod 600 "$f"
done

cron
exec "$@"

3.3 创建 Dockerfile ​

dockerfile
FROM ubuntu:24.04

RUN sed -i 's@//.*archive.ubuntu.com@//mirrors.aliyun.com@g' /etc/apt/sources.list.d/ubuntu.sources && \
    sed -i 's@//security.ubuntu.com@//mirrors.aliyun.com@g' /etc/apt/sources.list.d/ubuntu.sources && \
    sed -i 's@//ports.ubuntu.com@//mirrors.aliyun.com@g' /etc/apt/sources.list.d/ubuntu.sources

COPY docker-php-entrypoint /usr/local/bin/docker-php-entrypoint

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends software-properties-common ca-certificates && \
    LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
      locales cron php-pear \
      php7.2-cli php7.2-common php7.2-curl php7.2-dev php7.2-fpm php7.2-json \
      php7.2-mbstring php7.2-mcrypt php7.2-mysql php7.2-opcache php7.2-zip \
      php7.2-intl php7.2-gd php7.2-xml php7.2-redis && \
    locale-gen zh_CN.UTF-8 en_US.UTF-8 && \
    apt-get clean && rm -rf /var/lib/apt/lists/* && \
    chmod a+x /usr/local/bin/docker-php-entrypoint

RUN ln -sf /usr/sbin/php-fpm7.2 /usr/local/bin/php-fpm

ENV LANG=zh_CN.UTF-8
ENV LC_ALL=zh_CN.UTF-8

WORKDIR /var/www

# 入口脚本负责在启动 php-fpm 之前拉起 cron 守护进程
ENTRYPOINT ["docker-php-entrypoint"]
# -F 强制前台运行,避免 php-fpm 自行 daemonize 导致容器退出
CMD ["php-fpm", "-F"]

改用 PHP 7.4 / 8.3 时:包名中的 7.2 全部替换;PHP 8.x 没有 php8.3-json(已内置)和 php8.3-mcrypt,需从列表中删除。

3.4 构建镜像 ​

bash
cd /opt/php-7.2
docker build -t edusoho/php:7.2-security-2026 .

3.5 从镜像中复制 PHP 配置文件 ​

注意:本镜像的 PHP 是 apt 安装的,配置文件在 /etc/php/7.2/fpm/ 下。

bash
cd /opt/php-7.2
docker run --rm -v "$PWD/conf:/conf" edusoho/php:7.2-security-2026 \
  cp /etc/php/7.2/fpm/pool.d/www.conf /conf/www.conf
docker run --rm -v "$PWD/conf:/conf" edusoho/php:7.2-security-2026 \
  cp /etc/php/7.2/fpm/php.ini /conf/php.ini
sudo chown $(whoami):$(id -gn) conf/*

3.6 修改 PHP-FPM 进程数 ​

务必根据服务器内存和访问量调整以下参数(下面的数字仅为示例,偏保守):

bash
sed -i 's/^pm.max_children.*/pm.max_children = 5/'         ./conf/www.conf
sed -i 's/^pm.start_servers.*/pm.start_servers = 2/'       ./conf/www.conf
sed -i 's/^pm.min_spare_servers.*/pm.min_spare_servers = 1/' ./conf/www.conf
sed -i 's/^pm.max_spare_servers.*/pm.max_spare_servers = 3/' ./conf/www.conf

可参考原服务器 /etc/php/7.x/fpm/pool.d/www.conf 中的现有值。

3.7 修改监听端口为 9072 ​

bash
sed -i -E 's|^[[:space:]]*;?[[:space:]]*listen[[:space:]]*=.*|listen = 127.0.0.1:9072|' ./conf/www.conf
grep -n '^listen' ./conf/www.conf   # 应输出 listen = 127.0.0.1:9072

3.8 修改 php.ini ​

按实际情况修改 ./conf/php.ini,至少对照原服务器调整:upload_max_filesize、post_max_size、memory_limit、max_execution_time。

3.9 创建 docker-compose.yml ​

yaml
services:
  fpm:
    image: edusoho/php:7.2-security-2026
    restart: unless-stopped
    network_mode: host
    volumes:
      - /var/www:/var/www
      - ./conf/www.conf:/etc/php/7.2/fpm/pool.d/www.conf
      - ./conf/php.ini:/etc/php/7.2/fpm/php.ini
      - ./data/cron:/var/spool/cron
    environment:
      TZ: Asia/Shanghai

说明:

  • 使用宿主机网络,PHP-FPM 监听 127.0.0.1:9072。
  • 宿主机 /var/www 映射到容器内 /var/www。容器内路径必须与 Nginx 配置中的网站根目录一致(Nginx 把脚本绝对路径传给 PHP-FPM)。如果 EduSoho 不在 /var/www 下,请增加一行同路径映射,例如 - /data/edusoho:/data/edusoho。
  • 容器内以 www-data(UID 33)运行。Ubuntu 宿主机一致无需处理;CentOS 等系统上原运行用户 UID 不同,需将网站目录中需要写入的目录(如 app/cache、app/data、app/logs、web/files)属主改为 UID 33:sudo chown -R 33:33 <目录>。

3.10 启动服务 ​

bash
cd /opt/php-7.2
docker compose up -d
docker compose ps          # 状态应为 running
docker compose logs fpm    # 确认无报错

3.11 切换 Nginx ​

在站点配置中找到 fastcgi_pass,不论原来是 127.0.0.1:9000 还是 unix:/run/php/...sock,都改为:

nginx
fastcgi_pass 127.0.0.1:9072;
bash
sudo nginx -t && sudo nginx -s reload

然后访问网站,验证 EduSoho 前后台功能正常。

3.12 重新注册 EduSoho 定时任务 ​

(1) 删除宿主机上已注册的定时任务。 可能在 www-data 下,也可能在 root 下,一并删除。EduSoho 的定时任务形如:

*/1 * * * * /your/edusoho/app/console util:scheduler ...
*/1 * * * * /your/edusoho/app/console queue:work ...
bash
sudo crontab -u www-data -l   # 查看
sudo crontab -u www-data -e   # 编辑删除
sudo crontab -l               # root 查看
sudo crontab -e               # root 编辑删除

(2) 注册到容器内。 教培版本进入管理后台 https://你的域名/admin/v2/crontab,点击「重新初始化」,新的定时任务会注册到容器中。企培版本进入管理后台https://你的域名/admin/crontab,https://你的域名/admin/queue,新的定时任务会注册到容器中。

(3) 确认成功:

bash
cat /opt/php-7.2/data/cron/crontabs/www-data

能看到上述命令即注册成功。几分钟后可在后台定时任务页面确认任务有新的执行记录。

3.13 停止宿主机原 PHP-FPM ​

确认一切正常后,在宿主机执行(服务名按实际版本):

bash
sudo systemctl disable --now php7.2-fpm
# 无 systemd 的系统:sudo service php7.2-fpm stop

3.14 注意事项 ​

  • 执行 EduSoho 命令行脚本需在容器内执行:

    bash
    cd /opt/php-7.2
    docker compose exec -u www-data fpm bash
  • 卸载宿主机 PHP:Docker 版运行一段时间稳定后,再卸载宿主机 PHP,避免多版本并存造成混乱。


4. 宝塔面板部署 ​

宝塔面板管理的 PHP 有其独立的安装与配置方式,请按以下专项说明操作:

👉 https://mp.weixin.qq.com/s/pJ6mHOR01XEQlqLus2lwpg

操作前同样请先完成 §1 的备份。


5. 已经是 Docker 部署 ​

  • 如果镜像基于官方 php:7.x-fpm 镜像构建:官方 7.x 镜像已停止维护,不会再有安全修复。请改用 §3 的 Dockerfile 重新构建镜像,替换原镜像后重启容器。

  • 如果镜像基于 Ubuntu + Ondřej Surý PPA 构建:直接重新构建镜像(加 --no-cache 确保拉到最新包)并重启容器:

    bash
    docker build --no-cache -t <你的镜像名> .
    docker compose up -d

6. 顺带升级 PHP 大版本(可选,推荐) ​

PHP 7.x 均已停止官方维护,长期看建议升级到更高版本:

  • 教培版:先将 EduSoho 升级到 8.6.14,再将 PHP 升级到 7.4。
  • 企培版:先将 EduSoho 升级到 24.2.6,再将 PHP 升级到 8.3(仍在官方安全支持期内,推荐)。

顺序很重要:先升级 EduSoho,确认正常后再升级 PHP。 反过来会导致网站无法访问。

升级 PHP 大版本时,按 §2(安装新版本 phpX.Y-* 包,并把 Nginx 的 fastcgi_pass 指向新版本)或 §3(替换版本号后构建)执行。


7. 验证 ​

bash
# 直接部署
php -v
dpkg -l | grep php7.2-fpm        # 确认包版本已更新
# Docker 部署
cd /opt/php-7.2 && docker compose exec fpm php -v
docker compose exec fpm php -m   # 确认 mysql、redis、gd、intl 等扩展存在

然后检查:

  • [ ] 前台首页、课程页、登录正常
  • [ ] 后台可登录,上传图片/附件正常
  • [ ] 后台「定时任务」有新的执行记录
  • [ ] 视频/直播等业务功能正常

8. 回滚 ​

  • Docker 方案:把 Nginx 的 fastcgi_pass 改回原值并 reload,sudo systemctl start php7.2-fpm 启动原 PHP-FPM,用 §1 备份的 crontab-*.bak 恢复定时任务(sudo crontab -u www-data ~/crontab-www-data.bak),最后 docker compose down。
  • PPA 原地升级:联系 EduSoho 技术支持协助处理。

如遇问题请联系 EduSoho 技术支持,并附上 php -v 输出和 Nginx / PHP-FPM 错误日志。