# Docker 部署

<cite>
**本文引用的文件**
- [composer.json](file://composer.json)
- [README.md](file://README.md)
- [.example.env](file://.example.env)
- [public/index.php](file://public/index.php)
- [public/router.php](file://public/router.php)
- [.gitignore](file://.gitignore)
- [AGENTS.MD](file://AGENTS.MD)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [组件详解](#组件详解)
6. [依赖关系分析](#依赖关系分析)
7. [性能与资源](#性能与资源)
8. [故障排查](#故障排查)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本指南面向希望以 Docker 方式部署 ThinkCMF 的工程团队，围绕以下目标展开：给出可落地的 Dockerfile 示例思路（基础镜像、PHP 扩展、应用代码复制）、docker-compose 编排（Web、数据库、缓存）、容器网络与持久化（端口映射、数据卷、环境变量）、多阶段构建优化、生产最佳实践（健康检查、重启策略、资源限制）、监控与日志、升级与回滚策略及常见问题排查。

## 项目结构
- Web 入口与根目录
  - 入口文件位于 public/index.php，作为 HTTP 请求入口。
  - Web 根目录应指向 public/，由 public/router.php 进行路由转发至入口文件。
- 配置与环境
  - .env 环境变量通过 .example.env 提供参考键位；项目支持 .env 优先级高于静态配置。
- 依赖与运行时
  - composer.json 声明了 PHP 版本与必需扩展（JSON、CURL、PDO、MBSTRING、ZIP），以及 ThinkCMF 相关包。
- Docker 支持
  - README 明确项目支持 Docker 运行，并建议参考独立的 Docker 仓库。

```mermaid
graph TB
A["Web 根目录<br/>public/"] --> B["入口文件<br/>public/index.php"]
A --> C["路由转发<br/>public/router.php"]
D[".env 环境变量"] --> E["应用配置加载"]
F["Composer 依赖<br/>composer.json"] --> G["vendor/"]
B --> G
E --> B
```

图表来源
- [public/index.php:1-37](file://public/index.php#L1-L37)
- [public/router.php:1-20](file://public/router.php#L1-L20)
- [.example.env:1-1](file://.example.env#L1-L1)
- [composer.json:1-77](file://composer.json#L1-L77)

章节来源
- [public/index.php:1-37](file://public/index.php#L1-L37)
- [public/router.php:1-20](file://public/router.php#L1-L20)
- [.example.env:1-1](file://.example.env#L1-L1)
- [composer.json:1-77](file://composer.json#L1-L77)
- [README.md:113-118](file://README.md#L113-L118)

## 核心组件
- Web 服务（ThinkCMF 应用）
  - 基于 PHP 8.1+ 运行，依赖 JSON、CURL、PDO、MBSTRING、ZIP 扩展。
  - 入口为 public/index.php，Web 根目录指向 public/。
- 数据库服务（MySQL/MariaDB）
  - 通过 .env 中 DATABASE_* 变量进行连接配置。
- 缓存服务（Redis）
  - 通过 .env 中 REDIS_* 或相关缓存配置项接入。
- 构建与运行时
  - 使用 Composer 安装依赖，生产环境建议使用 --no-dev 与优化自动加载。

章节来源
- [composer.json:30-42](file://composer.json#L30-L42)
- [public/index.php:12-27](file://public/index.php#L12-L27)
- [.example.env:1-1](file://.example.env#L1-L1)
- [README.md:84-94](file://README.md#L84-L94)

## 架构总览
下图展示容器化部署的典型拓扑：前端 Nginx/Apache（可选）反向代理至 PHP-FPM/内置 HTTP 服务器，ThinkCMF 应用读取 .env 并连接 MySQL，Redis 用于缓存与会话。

```mermaid
graph TB
subgraph "容器层"
W["Web 应用容器<br/>ThinkCMF"]
DB["数据库容器<br/>MySQL/MariaDB"]
RC["缓存容器<br/>Redis"]
end
subgraph "网络"
NET["用户流量"]
end
NET --> W
W --> DB
W --> RC
```

图表来源
- [README.md:84-94](file://README.md#L84-L94)
- [.example.env:1-1](file://.example.env#L1-L1)

## 组件详解

### Dockerfile 编写要点
- 基础镜像
  - 选择官方 PHP 8.1+ 镜像（含 CLI 与 Apache/Nginx 可选），确保包含所需扩展。
- PHP 扩展
  - 安装 ext-json、ext-curl、ext-pdo、ext-mbstring、ext-zip。
- 应用代码复制与权限
  - 将仓库代码复制到镜像内，设置 WEB_ROOT 为 public/，并赋予 data/ 与 public/upload/ 写权限（生产环境建议最小权限）。
- Composer 安装
  - 在构建阶段执行 composer install --no-dev --optimize-autoloader，减少运行时体积。
- 入口与监听
  - 配置 Web 服务器指向 public/，或使用 PHP 内置 HTTP 服务器（仅开发测试）。

```mermaid
flowchart TD
S["开始"] --> Base["选择 PHP 8.1+ 基础镜像"]
Base --> Ext["安装 JSON/CURL/PDO/MBSTRING/ZIP 扩展"]
Ext --> Copy["复制应用代码到镜像"]
Copy --> Cfg["准备 .env 与配置目录"]
Cfg --> Com["执行 composer install --no-dev --optimize-autoloader"]
Com --> Perm["设置 data/ 与 public/upload/ 权限"]
Perm --> Entrypoint["配置 Web 根目录为 public/"]
Entrypoint --> Health["可选：健康检查"]
Health --> End["完成"]
```

### docker-compose 编排
- Web 服务
  - 依赖：PHP 8.1+、Composer 生成的 vendor、.env。
  - 端口映射：对外暴露 80/443（如需 HTTPS）。
  - 数据卷：挂载 data/、public/upload/ 以持久化配置与上传文件。
  - 环境变量：DATABASE_*、REDIS_*、APP_DEBUG=false。
- 数据库服务
  - MySQL 5.7+ 或 MariaDB，持久化数据卷至宿主机。
  - 初始化：首次启动可执行初始化脚本或等待应用迁移。
- 缓存服务
  - Redis，持久化可选；与应用通过 .env 连接。

```mermaid
graph LR
subgraph "Compose 编排"
Web["web 服务"]
MySQL["mysql 服务"]
Redis["redis 服务"]
end
Web --- MySQL
Web --- Redis
```

图表来源
- [.example.env:1-1](file://.example.env#L1-L1)
- [.gitignore:14-16](file://.gitignore#L14-L16)

### 容器网络与持久化
- 端口映射
  - Web：80/tcp、443/tcp（按需）。
- 数据卷
  - data/：动态配置与缓存等。
  - public/upload/：媒体与附件。
- 环境变量
  - DATABASE_*：主机、端口、数据库名、用户名、密码、字符集、前缀等。
  - REDIS_*：主机、端口、数据库索引、密码等。
  - APP_DEBUG=false（生产）。

章节来源
- [.example.env:1-1](file://.example.env#L1-L1)
- [.gitignore:14-16](file://.gitignore#L14-L16)
- [README.md:744-777](file://README.md#L744-L777)

### 多阶段构建优化
- 阶段一（构建）
  - 安装 build-essential、git、unzip 等构建依赖。
  - composer install --no-dev --optimize-autoloader。
- 阶段二（运行）
  - 仅拷贝 vendor 与应用代码，不包含构建依赖。
  - 使用更小的基础镜像（如 php:8.1-fpm-alpine），减少镜像体积与攻击面。

章节来源
- [composer.json:30-42](file://composer.json#L30-L42)
- [README.md:754-757](file://README.md#L754-L757)

### 生产环境最佳实践
- 健康检查
  - Web：GET / 且返回 200；或调用 /api/health（视应用提供）。
- 重启策略
  - unless-stopped 或 on-failure，避免无限重启。
- 资源限制
  - CPU/内存限额，结合 PHP-FPM 进程数与队列任务进行调优。
- 安全加固
  - 非 root 用户运行、只读根文件系统、最小权限卷挂载、禁用危险函数。

章节来源
- [README.md:744-777](file://README.md#L744-L777)

### 监控与日志
- 日志
  - Web 访问日志与错误日志输出至 stdout/stderr，便于容器平台采集。
  - 应用日志路径遵循 ThinkCMF 默认约定（data/log/*）。
- 监控
  - 指标：CPU、内存、QPS、错误率、数据库连接数。
  - 告警：阈值触发与健康检查失败告警。

章节来源
- [AGENTS.MD:744-777](file://AGENTS.MD#L744-L777)

### 升级与回滚策略
- 升级
  - 代码升级：拉取新镜像后滚动更新，先更新副本再替换。
  - 数据库迁移：在升级前备份，升级后执行迁移脚本。
- 回滚
  - 保留上一版本镜像与数据卷快照，回退到上一稳定版本。
- 发布窗口
  - 非业务高峰时段，预留回滚时间。

章节来源
- [README.md:119-181](file://README.md#L119-L181)

## 依赖关系分析
- PHP 版本与扩展
  - PHP >= 8.1.0，必需扩展 JSON、CURL、PDO、MBSTRING、ZIP。
- 应用依赖
  - ThinkCMF 核心包与 API、安装包、应用商店等。
- Web 入口
  - public/index.php 为单一入口，public/router.php 负责静态资源与路由转发。

```mermaid
graph LR
PHP["PHP 8.1+"] --> EXT1["ext-json"]
PHP --> EXT2["ext-curl"]
PHP --> EXT3["ext-pdo"]
PHP --> EXT4["ext-mbstring"]
PHP --> EXT5["ext-zip"]
APP["ThinkCMF 应用"] --> PHP
APP --> DB["MySQL/MariaDB"]
APP --> RC["Redis"]
```

图表来源
- [composer.json:30-42](file://composer.json#L30-L42)
- [public/index.php:12-27](file://public/index.php#L12-L27)

章节来源
- [composer.json:30-42](file://composer.json#L30-L42)
- [public/index.php:12-27](file://public/index.php#L12-L27)

## 性能与资源
- PHP-FPM 进程模型与池配置
  - 根据并发与内存占用调整 pm.max_children、pm.start_servers 等参数。
- 缓存策略
  - 启用 Redis 缓存与持久化会话，降低数据库压力。
- 存储与 IO
  - data/ 与 public/upload/ 使用高性能磁盘或网络存储，避免 IO 瓶颈。
- CDN 与静态资源
  - 静态资源走 CDN，减少 Web 层负载。

## 故障排查
- 无法访问或 500 错误
  - 检查 .env 是否正确（DATABASE_*、REDIS_*、APP_DEBUG）。
  - 查看应用日志与容器日志，确认数据库连通性与缓存可用性。
- 权限问题
  - data/ 与 public/upload/ 必须可写；容器内用户需具备写权限。
- PHP 扩展缺失
  - 确认镜像已安装 JSON、CURL、PDO、MBSTRING、ZIP。
- 数据库初始化
  - 首次启动执行数据库迁移脚本，确保表结构完整。
- Docker 仓库
  - 若无现成镜像，可参考 README 中提供的 Docker 仓库地址自行构建。

章节来源
- [README.md:113-118](file://README.md#L113-L118)
- [AGENTS.MD:744-777](file://AGENTS.MD#L744-L777)

## 结论
通过以上步骤，可在容器环境中稳定运行 ThinkCMF。建议以多阶段构建减小镜像体积，结合健康检查与资源限制提升稳定性，并建立完善的日志与监控体系，配合标准化的升级与回滚流程，保障生产环境的持续交付与快速恢复。

## 附录
- 关键文件定位
  - 入口与路由：[public/index.php:1-37](file://public/index.php#L1-L37)、[public/router.php:1-20](file://public/router.php#L1-L20)
  - 环境变量模板：[.example.env:1-1](file://.example.env#L1-L1)
  - 依赖与扩展：[composer.json:30-42](file://composer.json#L30-L42)
  - 部署与 Docker 说明：[README.md:113-118](file://README.md#L113-L118)、[AGENTS.MD:744-777](file://AGENTS.MD#L744-L777)
- 建议的 docker-compose 关键字段
  - ports、volumes、environment、depends_on、healthcheck、deploy（资源限制与重启策略）