thinkphp 5.1 可通过容器化、配置外置、服务编排等五步接入 docker swarm:使用多阶段构建轻量镜像,敏感配置用 secret/config 管理,nginx 与 php-fpm 分离部署,runtime 目录持久化挂载,队列服务设为全局模式。

ThinkPHP 5.1 是一个已停止官方维护的框架版本,但仍有大量老项目在稳定运行。若需将其接入 Docker Swarm 实现集群化部署,关键不在于“重写应用”,而在于合理封装、解耦环境依赖、适配 Swarm 的服务模型与生命周期管理。整个过程核心是:容器化 → 网络隔离 → 配置外置 → 服务编排 → 持久化分离。
容器化 TP5.1 应用(Nginx + PHP-FPM 架构)
TP5.1 默认依赖 Apache 或 Nginx + PHP 环境,Swarm 中推荐使用多阶段构建的轻量镜像:
- 基础镜像选
php:7.4-fpm-alpine(兼容 TP5.1 最高支持的 PHP 7.4),避免 Debian 大镜像; - Nginx 单独起一个服务(
nginx容器),通过fastcgi_pass指向 PHP-FPM 服务名(如php:9000),利用 Swarm 内置 DNS 自动解析; - 将
public/目录作为 Nginx 根路径,application/、config/等敏感目录**不暴露在 Web 容器中**,只挂载进 PHP 容器; - Dockerfile 中禁用
opcache.enable_cli=1,避免 CLI 模式下缓存干扰队列或命令行任务; - 入口脚本统一用
docker-entrypoint.sh做权限修复(如chown -R www-data:www-data /var/www)和配置生成(如根据环境变量写入database.php)。
配置与环境分离(Swarm Secret + Config)
TP5.1 的 config/database.php、config/app.php 等不能硬编码进镜像。Swarm 提供原生方案:
- 数据库密码、Redis 密钥等敏感信息,用
docker secret create db_password ./pwd.txt创建,挂载到 PHP 容器的/run/secrets/db_password; - 非敏感配置(如
app_debug、default_timezone)用docker config create app_config config.php,挂载为只读文件覆盖默认配置; - PHP 容器启动时,通过脚本读取 secret 和 config,动态生成
runtime/下的最终配置文件,再执行php start.php; - 禁止在代码中调用
getenv()直接读取宿主机环境变量——Swarm 中环境变量无法跨服务共享,必须显式注入或挂载。
服务定义与网络拓扑(Stack 部署)
使用 docker-compose.yml(v3.8+)编写 stack 文件,直接 docker stack deploy -c docker-compose.yml tp51 部署:
- 定义
php服务:副本数设为3,限制内存(如deploy.resources.limits.memory: 512M),防止 OOM 杀死进程; - 定义
nginx服务:副本数可设为2,挂载静态资源卷(./public:/var/www/html:ro),并配置healthcheck检测/ping接口; - 定义
redis和mysql服务:使用官方镜像,通过networks加入同一tp51-net覆盖网络,无需暴露端口给外部,仅限内部通信; - 所有服务共用自定义 overlay 网络:
tp51-net,启用加密(driver_opts: { "encrypted": "true" })保障内网传输安全; - 添加
deploy.restart_policy.condition: on-failure,确保 PHP 进程崩溃后自动重启,避免单点失效。
持久化与日志处理(规避 Swarm 局限)
TP5.1 的 runtime/ 目录含缓存、日志、session,不能放在容器内:
- 用命名卷(
volume)挂载php服务的/var/www/runtime,卷驱动建议local并设置o=uid=82,gid=82(匹配 www-data 用户); - 日志不写本地文件,改用
error_log syslog和access_log /dev/stdout,由 Swarm 统一采集(docker service logs tp51_php可实时查看); - 上传文件目录(如
public/uploads)单独挂载 NFS 或对象存储网关(如 MinIO),避免节点间不同步; - 清除
runtime/cache/不再依赖定时脚本——改用 Redis 缓存驱动,彻底脱离文件系统依赖。
不复杂但容易忽略:TP5.1 的 think queue 队列进程需单独部署为全局服务(deploy.mode: global),并确保与 PHP Web 服务共享相同的 secrets/config,否则异步任务无法连接数据库。











