
不知不觉,用 PHP 7 跑博客已经十个年头了
,服务器上的版本还停留在 PHP 7.4.x。
这套环境用了这么多年,也是时候升级到 PHP 8 了!
这次选的是 PHP 8.5.10,顺便把之前的 Dockerfile 整理了一下。
从一键安装包到 Docker
最开始,我用 LNMP 一键包在服务器上直接编译安装运行环境。后来虽然换成了 OneinStack,但还是在宿主机上编译安装,本质上没什么变化。
这样用起来倒也方便,就是时间一长,各种依赖和配置都堆在宿主机上,升级、迁移都不太省心。稍有不慎环境就搞挂了,恢复起来简直就是灾难。
后来容器化流行起来,我就把运行环境都搬进了 Docker,一直沿用到现在。
换成容器之后,确实省心了不少。以前换台服务器,还得重新装环境、配依赖、改配置;现在把镜像、配置和网站文件准备好,启动容器就能继续用。后面再升级或者迁移,也不用在宿主机上折腾一遍依赖了。
顺手整理一下 Dockerfile
现在博客的 PHP 就跑在 Docker 容器里。之前用的是 php:7.4-fpm 官方镜像,在上面安装了 GD、Imagick、Memcached 等一堆扩展。这次升级,我也借助 AI 把 Dockerfile 梳理了一遍,按现在博客和插件的使用情况,去掉了用不上的依赖。
新的 Dockerfile 如下:
# PHP 版本和 FPM 基础镜像。
ARG PHP_VERSION=8.5.10
FROM php:${PHP_VERSION}-fpm-bookworm
# 腾讯云内网 Debian 镜像,仅用于部署在腾讯云内的生产构建。
ARG DEBIAN_MIRROR=http://mirrors.tencentyun.com/debian
ARG DEBIAN_SECURITY_MIRROR=http://mirrors.tencentyun.com/debian-security
# 容器时区和 apt 非交互模式。
ENV TZ=Asia/Shanghai \
DEBIAN_FRONTEND=noninteractive
# Typecho 和已安装插件所需扩展;XML、OPcache 等由 PHP 8.5 基础镜像提供。
# 构建时验证扩展并清理缓存;PHP 8.5 中 OPcache 名称为 Zend OPcache。
RUN set -eux; \
for source_file in /etc/apt/sources.list /etc/apt/sources.list.d/debian.sources; do \
if [ -f "${source_file}" ]; then \
sed -ri \
-e "s@https?://(deb|security)\.debian\.org/debian-security@${DEBIAN_SECURITY_MIRROR}@g" \
-e "s@https?://deb\.debian\.org/debian@${DEBIAN_MIRROR}@g" \
"${source_file}"; \
fi; \
done; \
apt-get update; \
apt-get install -y --no-install-recommends \
unzip \
libicu-dev; \
docker-php-ext-install -j"$(nproc)" \
intl \
mysqli \
pdo_mysql; \
php -r 'foreach (["curl", "fileinfo", "intl", "json", "mbstring", "mysqli", "openssl", "pdo_mysql", "Reflection", "xml", "Zend OPcache"] as $extension) { if (!extension_loaded($extension)) { fwrite(STDERR, $extension . " is missing" . PHP_EOL); exit(1); } }'; \
apt-get clean; \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# 使用官方 PHP-FPM 镜像默认 CMD,保持 FPM 在前台运行。这里把 PHP 版本提成了 PHP_VERSION 参数,后续升级小版本,可以通过构建参数指定版本,再检查一下依赖是否需要调整,重新构建就行。
另外加了一步扩展检查,缺少列出的扩展就直接让构建失败,免得等容器启动之后才发现少了东西。
这份扩展列表是按我这次的使用情况整理的,换了主题、插件,或者启用新的功能,还是得看各自需要什么。APT 源用的也是腾讯云内网地址,在其他环境构建时需要换成能访问的源。
构建并启动 PHP 8
Docker Compose 配置如下:
services:
php8:
image: php:8.5.10-fpm
build:
context: /data/docker/php8
dockerfile: Dockerfile
args:
PHP_VERSION: "8.5.10"
container_name: php8
working_dir: /data/wwwroot
volumes:
- "/data/wwwroot:/data/wwwroot"
- "./config/custom-php.ini:/usr/local/etc/php/conf.d/zz-custom.ini:ro"
- "./config/custom-php-fpm.conf:/usr/local/etc/php-fpm.d/zz-custom.conf:ro"
expose:
- "9001"
environment:
- TZ=Asia/Shanghai
networks:
- local_network
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "5"
healthcheck:
test: ["CMD-SHELL", "php-fpm -tt >/dev/null 2>&1"]
interval: 30s
timeout: 5s
retries: 3
networks:
local_network:
name: local_network
external: true这份配置沿用了我的网站目录、配置文件和 Docker 网络。照着用的话,需要先准备好挂载的两个配置文件和 local_network 网络,再把路径改成自己的。
还有一个容易忽略的地方:expose 里写了 9001,并不会自动把 PHP-FPM 的监听端口改成 9001。FPM 配置里的监听端口,以及 Web 服务连接 PHP-FPM 的地址和端口,都要对应上。
接下来重新构建、启动容器,检查扩展、FPM 配置和日志:
docker compose build --pull --no-cache php8
docker compose up -d php8
docker compose exec php8 php -m
docker compose exec php8 php-fpm -tt
docker compose logs --tail=200 php8再看一下版本:
[root@SKY-Debian php8]# docker compose exec php8 php -v
PHP 8.5.10 (cli) (built: Sep 19 2026 00:26:35) (NTS)
Copyright (c) The PHP Group
Built by https://github.com/docker-library/php
Zend Engine v4.5.10, Copyright (c) Zend Technologies
with Zend OPcache v8.5.10, Copyright (c), by Zend Technologies到这里,新的 PHP 环境就起来了。不过,命令行里显示 PHP 8.5.10,还不代表博客和插件都能正常工作。
上面的 php-fpm -tt 检查的是 FPM 配置,Compose 里的健康检查用的也是这条命令。首页、后台、评论和附件上传这些功能,还得打开网站实际试一下。
环境换好了,老插件还得折腾
容器化让环境升级简单了不少,但软件兼容性的问题还是绕不过去。升级前,最好先看一下自己用的 Typecho 版本、主题和插件对目标 PHP 版本的支持情况。
这次让我费心的主要是几个老插件。验证码、表情这些插件还好,主要是一些旧函数调用需要修修补补。比较麻烦的是原来的七牛云上传插件,修起来工作量不小
,索性把静态文件迁到了腾讯云。毕竟是腾讯云老用户,还有免费的存储额度可以用。
后来又偶然发现了一个上传插件:PicUp。
支持的第三方存储服务不少,腾讯云、七牛云都有,后台也做得挺好看。
我在这次的 PHP 8.5 环境下试了试,用着不错,给作者点个赞!
顺便补一句,PicUp 的图片压缩、WebP 转换和水印功能需要 GD。我上面的 Dockerfile 没有安装 GD,如果要用这些功能,还得把对应扩展补上,WebP 转换也要有相应支持。具体要求可以看插件的项目说明。
博客继续折腾着
这次升级整体还算顺利,时间主要花在了老插件上。
以前碰到报错,基本就是查文档、搜 Google、翻 GitHub Issue,再一点点读源码。现在多了 AI 帮忙,定位问题快了不少,改完再自己验证一下,确实省了不少工夫。
从手动编译 LNMP,到 Docker 容器化,再到如今用 AI 辅助开发,工具一直在变,折腾博客这件事倒是一直没变。
PHP 7 陪我走过了十年,这次也算正式迈进 PHP 8 时代了。环境更新了,博客继续折腾着。 