mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-01 15:32:48 +08:00
feat(stack): 新增 docker-dev 开发模式并自动清理文件
All checks were successful
build-and-deploy / 直传代码并部署到 Host15 (push) Successful in 1m13s
All checks were successful
build-and-deploy / 直传代码并部署到 Host15 (push) Successful in 1m13s
- 新增 docker-dev 部署模式,提供包含 nginx+php-fpm、MySQL、Redis、phpMyAdmin 和 Xdebug 的完整 Docker 开发环境 - 在 StackModeService 中重写 applyMode 方法,切换模式时自动删除目标模式中不存在的已管理文件 - 新增 .docker-dev.env 配置文件并纳入 managed_files 管理,切换模式时自动复制或删除
This commit is contained in:
58
.sisyphus/boulder.json
Normal file
58
.sisyphus/boulder.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"active_plan": "C:\\www\\ulthon_admin\\.sisyphus\\plans\\docker-dev-mode.md",
|
||||
"started_at": "2026-04-29T15:02:21.764Z",
|
||||
"session_ids": [
|
||||
"ses_22689140cffePScUfKV6YQhKuw",
|
||||
"ses_22627716cffeAYM2MF7Pk6Imqf",
|
||||
"ses_226277150ffeEvywS94KOh1bbx",
|
||||
"ses_226277119ffeScdvyzks7o5yiA",
|
||||
"ses_226277102ffe05M6aAKtXJs77v"
|
||||
],
|
||||
"session_origins": {
|
||||
"ses_22689140cffePScUfKV6YQhKuw": "direct",
|
||||
"ses_22627716cffeAYM2MF7Pk6Imqf": "appended",
|
||||
"ses_226277150ffeEvywS94KOh1bbx": "appended",
|
||||
"ses_226277119ffeScdvyzks7o5yiA": "appended",
|
||||
"ses_226277102ffe05M6aAKtXJs77v": "appended"
|
||||
},
|
||||
"plan_name": "docker-dev-mode",
|
||||
"agent": "atlas",
|
||||
"task_sessions": {
|
||||
"todo:1": {
|
||||
"task_key": "todo:1",
|
||||
"task_label": "1",
|
||||
"task_title": "创建 `source/stack/docker-dev/Dockerfile`",
|
||||
"session_id": "ses_22639e577ffecCxpGhpI4PgEqn",
|
||||
"agent": "Sisyphus-Junior",
|
||||
"category": "unspecified-high",
|
||||
"updated_at": "2026-04-29T15:09:23.263Z"
|
||||
},
|
||||
"todo:6": {
|
||||
"task_key": "todo:6",
|
||||
"task_label": "6",
|
||||
"task_title": "重写 `app/common/service/stack/StackModeService.php`,增加自动删除",
|
||||
"session_id": "ses_226335aa9ffeeb8XkZ0MS93Z4u",
|
||||
"agent": "Sisyphus-Junior",
|
||||
"category": "deep",
|
||||
"updated_at": "2026-04-29T15:13:38.842Z"
|
||||
},
|
||||
"todo:7": {
|
||||
"task_key": "todo:7",
|
||||
"task_label": "7",
|
||||
"task_title": "模式切换与 Docker 构建集成验证",
|
||||
"session_id": "ses_2262d0c99ffeLkxFbi8pwpEeAm",
|
||||
"agent": "Sisyphus-Junior",
|
||||
"category": "deep",
|
||||
"updated_at": "2026-04-29T15:21:13.686Z"
|
||||
},
|
||||
"final-wave:f1": {
|
||||
"task_key": "final-wave:f1",
|
||||
"task_label": "F1",
|
||||
"task_title": "**Plan Compliance Audit** — `oracle`",
|
||||
"session_id": "ses_226221517ffenAR0cwB0Y2KKl1",
|
||||
"agent": "Sisyphus-Junior",
|
||||
"category": "quick",
|
||||
"updated_at": "2026-04-29T15:32:12.642Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
568
.sisyphus/plans/docker-dev-mode.md
Normal file
568
.sisyphus/plans/docker-dev-mode.md
Normal file
@@ -0,0 +1,568 @@
|
||||
# 新增 docker-dev 部署模式
|
||||
|
||||
## TL;DR
|
||||
|
||||
> **Quick Summary**: 在 `source/stack/` 下新增 `docker-dev` 模式,提供完整的 Docker 开发环境(nginx+php-fpm 并发处理、内置定时器、MySQL、Redis、phpMyAdmin、Xdebug 调试),替代 `php think run` 的单线程限制。
|
||||
>
|
||||
> **Deliverables**:
|
||||
> - `source/stack/docker-dev/Dockerfile` — 基于 full 模式 + Xdebug + 开发优化 PHP 配置
|
||||
> - `source/stack/docker-dev/docker-compose.yaml` — 多服务编排(app、mysql、redis、phpmyadmin)
|
||||
> - `source/stack/docker-dev/.docker-dev.env` — 开发环境专用配置(HOSTNAME=mysql 等)
|
||||
> - `source/stack/stack.json` — 注册 docker-dev 模式 + managed_files 增加 .docker-dev.env
|
||||
> - `app/common/service/stack/StackModeService.php` — 重写 applyMode,切换时自动删除多余文件
|
||||
> - `.gitignore` — 排除 `docker-dev/` 数据目录
|
||||
>
|
||||
> **Estimated Effort**: Medium
|
||||
> **Parallel Execution**: YES - 3 waves
|
||||
> **Critical Path**: Task 1-5 (parallel) → Task 6 → Task 7 → F1-F4
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
### Original Request
|
||||
开发环境中 `php think run` 是单线程的,无法并发处理请求,也缺少定时器等完整运行支持。需要增加一个 Docker 开发模式,提供生产级运行环境用于本地开发调试。
|
||||
|
||||
### Interview Summary
|
||||
**Key Discussions**:
|
||||
- 镜像基础:基于 full 模式(FROM php:8.2-fpm-bookworm),不依赖预构建基础镜像
|
||||
- 服务组件:MySQL 8 + Redis + phpMyAdmin + Xdebug
|
||||
- 环境配置:独立文件 `.docker-dev.env`,不替换 `.example.env`;纳入 managed_files 管理
|
||||
- 端口映射:`1+原端口` 方案(8800/13306/16379/18888),避免与本地服务冲突
|
||||
- 数据持久化:MySQL/Redis 数据映射到项目根目录 `./docker-dev/`
|
||||
- 多余文件清理:切换回 default 时,自动删除目标模式不存在的已管理文件(需重写 applyMode)
|
||||
- 无需 CI/CD:dev 模式不提供 `.gitea/workflows/` 文件,自动 fallback 到 default
|
||||
|
||||
**Research Findings**:
|
||||
- Metis 确认:ThinkPHP `Env::load()` 中 `parse_ini_file()` 的结果直接覆盖 `$_ENV`,`.env` 文件值始终优先于 Docker 环境变量
|
||||
- `docker/run.sh` 已内置 timer + nginx + php-fpm 启动逻辑,无需修改
|
||||
- `conf.d/` 按 ASCII 排序加载,dev 配置文件需命名为 `zzz-` 前缀以覆盖 `zz-phprun.ini`
|
||||
- 当前 `applyMode` 只做复制,不做删除;`rollback` 有删除逻辑可参考
|
||||
|
||||
### Metis Review
|
||||
**Identified Gaps** (addressed):
|
||||
- 环境变量优先级反转:不依赖 docker-compose environment 覆盖,改用独立 `.docker-dev.env` 文件
|
||||
- conf.d 文件排序:dev PHP 配置命名为 `zzz-dev.ini` 确保最后加载
|
||||
- Linux 兼容性:添加 `extra_hosts: host.docker.internal:host-gateway`
|
||||
- MySQL 启动依赖:使用 `healthcheck` + `depends_on: condition: service_healthy`
|
||||
- Xdebug 与 JIT 冲突:dev 配置中彻底关闭 opcache
|
||||
|
||||
---
|
||||
|
||||
## Work Objectives
|
||||
|
||||
### Core Objective
|
||||
创建一个开箱即用的 Docker 开发环境模式,解决 `php think run` 的并发限制和定时器缺失问题,同时集成常用开发服务(MySQL、Redis、phpMyAdmin、Xdebug)。
|
||||
|
||||
### Concrete Deliverables
|
||||
- `source/stack/docker-dev/Dockerfile`
|
||||
- `source/stack/docker-dev/docker-compose.yaml`
|
||||
- `source/stack/docker-dev/.docker-dev.env`
|
||||
- `source/stack/stack.json` (更新 modes + managed_files)
|
||||
- `app/common/service/stack/StackModeService.php` (重写 applyMode 增加自动删除)
|
||||
- `.gitignore` (添加 `/docker-dev/`)
|
||||
|
||||
### Definition of Done
|
||||
- [ ] `php think admin:stack:mode list` 输出包含 docker-dev
|
||||
- [ ] `php think admin:stack:mode use docker-dev` 成功切换,根目录出现 `.docker-dev.env`
|
||||
- [ ] `copy .docker-dev.env .env` 后 `docker compose build` 构建成功
|
||||
- [ ] `docker compose up -d` 所有 4 个服务运行正常
|
||||
- [ ] 应用可正常连接 MySQL(端口 13306)
|
||||
- [ ] Xdebug 扩展已加载
|
||||
- [ ] opcache 已关闭、display_errors 已开启
|
||||
- [ ] `php think admin:stack:mode use default` 切回后,`.docker-dev.env` 从根目录自动删除
|
||||
|
||||
### Must Have
|
||||
- Dockerfile 基于 `php:8.2-fpm-bookworm`,包含 full 模式的所有 PHP 扩展 + Xdebug
|
||||
- docker-compose 包含 app、mysql、redis、phpmyadmin 四个服务
|
||||
- 端口使用 `1+原端口` 方案:HTTP 8800、MySQL 13306、Redis 16379、phpMyAdmin 18888
|
||||
- MySQL 带健康检查,app 服务等待 MySQL 就绪后再启动
|
||||
- 开发优化的 PHP 配置(关闭 opcache、开启 display_errors)
|
||||
- Xdebug 配置(client_host=host.docker.internal,trigger 模式)
|
||||
- Linux 兼容性(extra_hosts)
|
||||
- 数据持久化到 `./docker-dev/`
|
||||
- `.docker-dev.env` 纳入 managed_files,`.example.env` 不动
|
||||
- 切换模式时自动删除目标模式不存在的已管理文件
|
||||
|
||||
### Must NOT Have (Guardrails)
|
||||
- 不修改 `docker/run.sh`(复用现有启动逻辑)
|
||||
- 不修改 `extend/base/` 下的任何文件(在 app 层重写 applyMode)
|
||||
- 不修改 `.example.env`
|
||||
- 不修改已有模式(default、full、base-build)的文件内容
|
||||
- 不创建 `source/stack/docker-dev/docker/` 子目录
|
||||
- 不创建 `.gitea/workflows/` 文件
|
||||
- 不在 docker-compose `environment:` 中设置 ThinkPHP 数据库配置(无效)
|
||||
- 不使用 `composer install --no-dev`
|
||||
- 不设置 `opcache.jit` 相关配置(与 Xdebug 冲突)
|
||||
|
||||
---
|
||||
|
||||
## Verification Strategy
|
||||
|
||||
> **ZERO HUMAN INTERVENTION** - ALL verification is agent-executed.
|
||||
|
||||
### Test Decision
|
||||
- **Automated tests**: None(基础设施配置 + 小范围代码修改)
|
||||
- **Framework**: N/A
|
||||
|
||||
### QA Policy
|
||||
Every task includes agent-executed QA scenarios.
|
||||
Evidence saved to `.sisyphus/evidence/task-{N}-{scenario-slug}.{ext}`.
|
||||
|
||||
---
|
||||
|
||||
## Execution Strategy
|
||||
|
||||
### Parallel Execution Waves
|
||||
|
||||
```
|
||||
Wave 1 (Start Immediately - 所有文件创建可并行):
|
||||
+-- Task 1: 创建 source/stack/docker-dev/Dockerfile [unspecified-high]
|
||||
+-- Task 2: 创建 source/stack/docker-dev/docker-compose.yaml [unspecified-high]
|
||||
+-- Task 3: 创建 source/stack/docker-dev/.docker-dev.env [quick]
|
||||
+-- Task 4: 更新 source/stack/stack.json [quick]
|
||||
+-- Task 5: 更新 .gitignore [quick]
|
||||
|
||||
Wave 2 (After Task 4 - 代码修改):
|
||||
+-- Task 6: 重写 app 层 StackModeService (depends: 4) [deep]
|
||||
|
||||
Wave 3 (After ALL - 集成验证):
|
||||
+-- Task 7: 模式切换与 Docker 构建集成验证 (depends: 1-6) [deep]
|
||||
|
||||
Wave FINAL:
|
||||
+-- F1-F4: 并行审查
|
||||
|
||||
Critical Path: Task 4 → Task 6 → Task 7 → F1-F4
|
||||
Max Concurrent: 5 (Wave 1)
|
||||
```
|
||||
|
||||
### Dependency Matrix
|
||||
|
||||
| Task | Depends On | Blocks | Wave |
|
||||
|------|-----------|--------|------|
|
||||
| 1 | - | 7 | 1 |
|
||||
| 2 | - | 7 | 1 |
|
||||
| 3 | - | 7 | 1 |
|
||||
| 4 | - | 6, 7 | 1 |
|
||||
| 5 | - | 7 | 1 |
|
||||
| 6 | 4 | 7 | 2 |
|
||||
| 7 | 1-6 | F1-F4 | 3 |
|
||||
|
||||
### Agent Dispatch Summary
|
||||
|
||||
- **Wave 1**: 5 agents - T1 `unspecified-high`, T2 `unspecified-high`, T3-T5 `quick`
|
||||
- **Wave 2**: 1 agent - T6 `deep`
|
||||
- **Wave 3**: 1 agent - T7 `deep`
|
||||
- **FINAL**: 4 agents - F1 `oracle`, F2-F3 `unspecified-high`, F4 `deep`
|
||||
|
||||
---
|
||||
|
||||
## TODOs
|
||||
|
||||
- [x] 1. 创建 `source/stack/docker-dev/Dockerfile`
|
||||
|
||||
**What to do**:
|
||||
- 基于 `source/stack/full/Dockerfile` 创建,保留全部内容
|
||||
- PHP 扩展安装末尾追加 `install-php-extensions xdebug`
|
||||
- `composer install` 去掉 `--no-dev` 和 `--no-autoloader`
|
||||
- `composer dump-autoload` 去掉所有优化参数
|
||||
- 用 `RUN` 写入 `/usr/local/etc/php/conf.d/zzz-dev.ini`:
|
||||
```ini
|
||||
opcache.enable = 0
|
||||
opcache.jit_buffer_size = 0
|
||||
display_errors = On
|
||||
error_reporting = E_ALL
|
||||
```
|
||||
- 用 `RUN` 写入 `/usr/local/etc/php/conf.d/zzz-xdebug.ini`:
|
||||
```ini
|
||||
xdebug.mode = debug,develop
|
||||
xdebug.start_with_request = trigger
|
||||
xdebug.client_host = host.docker.internal
|
||||
xdebug.client_port = 9003
|
||||
xdebug.discover_client_host = true
|
||||
xdebug.idekey = DOCKER_DEV
|
||||
```
|
||||
|
||||
**Must NOT do**: 不创建 docker/ 子目录、不修改 run.sh、不用 --no-dev
|
||||
|
||||
**Recommended Agent Profile**: `unspecified-high`, Skills: `[]`
|
||||
|
||||
**Parallelization**: Wave 1, Blocks: 7, Blocked By: None
|
||||
|
||||
**References**:
|
||||
- `source/stack/full/Dockerfile` — 基础模板
|
||||
- `docker/zz-phprun.ini` — 需要覆盖的配置项
|
||||
- `docker/run.sh` — 第 8-9 行复制 zz-phprun.ini 到 conf.d
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: 包含 Xdebug 和开发配置
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. findstr "xdebug" source/stack/docker-dev/Dockerfile → 含 install-php-extensions xdebug
|
||||
2. findstr "zzz-dev.ini" source/stack/docker-dev/Dockerfile → 存在
|
||||
3. findstr "zzz-xdebug.ini" source/stack/docker-dev/Dockerfile → 存在
|
||||
4. findstr "no-dev" source/stack/docker-dev/Dockerfile → 无输出
|
||||
Evidence: .sisyphus/evidence/task-1-check.txt
|
||||
```
|
||||
|
||||
**Commit**: YES - `feat(stack): 新增 docker-dev 开发模式`
|
||||
|
||||
---
|
||||
|
||||
- [x] 2. 创建 `source/stack/docker-dev/docker-compose.yaml`
|
||||
|
||||
**What to do**:
|
||||
- 4 个服务:
|
||||
|
||||
**app** (`ulthon_admin`):
|
||||
- `build` from Dockerfile, `restart: unless-stopped`
|
||||
- `ports: "8800:80"`, `volumes: ./:/var/www/html`
|
||||
- `extra_hosts: host.docker.internal:host-gateway`
|
||||
- `depends_on: mysql: condition: service_healthy`
|
||||
|
||||
**mysql**:
|
||||
- `image: mysql:8.0`, `ports: "13306:3306"`
|
||||
- `environment: MYSQL_ROOT_PASSWORD=root, MYSQL_DATABASE=ulthon`
|
||||
- `volumes: ./docker-dev/mysql:/var/lib/mysql`
|
||||
- `healthcheck: mysqladmin ping, interval 10s, retries 5`
|
||||
|
||||
**redis**:
|
||||
- `image: redis:7-alpine`, `ports: "16379:6379"`
|
||||
- `volumes: ./docker-dev/redis:/data`
|
||||
|
||||
**phpmyadmin**:
|
||||
- `image: phpmyadmin:latest`, `ports: "18888:80"`
|
||||
- `environment: PMA_HOST: mysql`
|
||||
- `depends_on: mysql: condition: service_healthy`
|
||||
|
||||
- `name: ulthon_admin`,格式与 default/docker-compose.yaml 一致
|
||||
|
||||
**Must NOT do**: 不在 app environment 设 DATABASE_*、不用 restart: always
|
||||
|
||||
**Recommended Agent Profile**: `unspecified-high`, Skills: `[]`
|
||||
|
||||
**Parallelization**: Wave 1, Blocks: 7, Blocked By: None
|
||||
|
||||
**References**:
|
||||
- `source/stack/default/docker-compose.yaml` — 格式参考
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: 语法和内容验证
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. docker compose -f source/stack/docker-dev/docker-compose.yaml config → 无错误
|
||||
2. findstr "8800" source/stack/docker-dev/docker-compose.yaml → 存在
|
||||
3. findstr "13306" source/stack/docker-dev/docker-compose.yaml → 存在
|
||||
4. findstr "16379" source/stack/docker-dev/docker-compose.yaml → 存在
|
||||
5. findstr "18888" source/stack/docker-dev/docker-compose.yaml → 存在
|
||||
6. findstr "mysqladmin" source/stack/docker-dev/docker-compose.yaml → 存在
|
||||
7. findstr "host.docker.internal" source/stack/docker-dev/docker-compose.yaml → 存在
|
||||
Evidence: .sisyphus/evidence/task-2-check.txt
|
||||
```
|
||||
|
||||
**Commit**: YES - `feat(stack): 新增 docker-dev 开发模式`
|
||||
|
||||
---
|
||||
|
||||
- [x] 3. 创建 `source/stack/docker-dev/.docker-dev.env`
|
||||
|
||||
**What to do**:
|
||||
- 基于根目录 `.example.env` 创建
|
||||
- 顶部注释:`# Docker 开发模式配置 - 使用方式: copy .docker-dev.env .env`
|
||||
- 修改:`HOSTNAME=mysql`, `DATABASE=ulthon`, `USERNAME=root`, `PASSWORD=root`, `HOSTPORT=13306`
|
||||
- 其余不变
|
||||
|
||||
**Must NOT do**: 不修改 `.example.env`
|
||||
|
||||
**Recommended Agent Profile**: `quick`, Skills: `[]`
|
||||
|
||||
**Parallelization**: Wave 1, Blocks: 7, Blocked By: None
|
||||
|
||||
**References**: `.example.env`
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: 配置项验证
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. findstr "HOSTNAME" source/stack/docker-dev/.docker-dev.env → HOSTNAME=mysql
|
||||
2. findstr "HOSTPORT" source/stack/docker-dev/.docker-dev.env → HOSTPORT=13306
|
||||
3. findstr "USERNAME" source/stack/docker-dev/.docker-dev.env → USERNAME=root
|
||||
4. findstr "PASSWORD" source/stack/docker-dev/.docker-dev.env → PASSWORD=root
|
||||
5. findstr "DATABASE" source/stack/docker-dev/.docker-dev.env → DATABASE=ulthon
|
||||
Evidence: .sisyphus/evidence/task-3-check.txt
|
||||
```
|
||||
|
||||
**Commit**: YES - `feat(stack): 新增 docker-dev 开发模式`
|
||||
|
||||
---
|
||||
|
||||
- [x] 4. 更新 `source/stack/stack.json`
|
||||
|
||||
**What to do**:
|
||||
- `managed_files` 末尾追加 `".docker-dev.env"`
|
||||
- `modes` 添加:
|
||||
```json
|
||||
"docker-dev": {
|
||||
"description": "Docker 开发模式(nginx+php-fpm+MySQL+Redis+phpMyAdmin+Xdebug)",
|
||||
"author_only": false
|
||||
}
|
||||
```
|
||||
|
||||
**Must NOT do**: 不改 default_mode、不改已有模式
|
||||
|
||||
**Recommended Agent Profile**: `quick`, Skills: `[]`
|
||||
|
||||
**Parallelization**: Wave 1, Blocks: 6 & 7, Blocked By: None
|
||||
|
||||
**References**: `source/stack/stack.json`
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: JSON 和注册验证
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. php -r "json_decode(file_get_contents('source/stack/stack.json')); echo json_last_error()===JSON_ERROR_NONE?'VALID':'INVALID';" → VALID
|
||||
2. php -r "$j=json_decode(file_get_contents('source/stack/stack.json'),true); echo count($j['managed_files']);" → 4
|
||||
3. php think admin:stack:mode list → 包含 docker-dev
|
||||
Evidence: .sisyphus/evidence/task-4-check.txt
|
||||
```
|
||||
|
||||
**Commit**: YES - `feat(stack): 新增 docker-dev 开发模式`
|
||||
|
||||
---
|
||||
|
||||
- [x] 5. 更新 `.gitignore`
|
||||
|
||||
**What to do**: 添加 `/docker-dev/`
|
||||
|
||||
**Recommended Agent Profile**: `quick`, Skills: `[]`
|
||||
|
||||
**Parallelization**: Wave 1, Blocks: 7, Blocked By: None
|
||||
|
||||
**References**: `.gitignore`
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: 排除规则
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. findstr "docker-dev" .gitignore → 输出 /docker-dev/
|
||||
Evidence: .sisyphus/evidence/task-5-check.txt
|
||||
```
|
||||
|
||||
**Commit**: YES - `feat(stack): 新增 docker-dev 开发模式`
|
||||
|
||||
---
|
||||
|
||||
- [x] 6. 重写 `app/common/service/stack/StackModeService.php`,增加自动删除
|
||||
|
||||
**What to do**:
|
||||
- 在 `app/common/service/stack/StackModeService.php` 中重写 `applyMode` 方法
|
||||
- 调用 `parent::applyMode()` 执行原有的复制逻辑
|
||||
- 然后遍历 `managed_files`,对于**目标模式和 default 都不存在**的已管理文件,从根目录删除
|
||||
- 输出日志提示用户哪些文件被清理
|
||||
|
||||
**实现逻辑**(伪代码):
|
||||
```php
|
||||
public function applyMode(string $mode, string $operator = ''): array
|
||||
{
|
||||
$result = parent::applyMode($mode, $operator);
|
||||
|
||||
$stackConfig = json_decode(file_get_contents(root_path() . 'source/stack/stack.json'), true);
|
||||
$managedFiles = $stackConfig['managed_files'] ?? [];
|
||||
|
||||
foreach ($managedFiles as $file) {
|
||||
$targetPath = root_path() . $file;
|
||||
if (!file_exists($targetPath)) {
|
||||
continue;
|
||||
}
|
||||
$modeFile = root_path() . "source/stack/{$mode}/{$file}";
|
||||
$defaultFile = root_path() . "source/stack/default/{$file}";
|
||||
if (!file_exists($modeFile) && !file_exists($defaultFile)) {
|
||||
@unlink($targetPath);
|
||||
// 记录到 result 或日志
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
```
|
||||
|
||||
**Must NOT do**:
|
||||
- 不修改 `extend/base/common/service/stack/StackModeServiceBase.php`
|
||||
- 不删除非 managed_files 中的文件
|
||||
|
||||
**Recommended Agent Profile**: `deep`, Skills: [`ulthon-base-app-architecture`]
|
||||
|
||||
**Parallelization**: Wave 2, Blocks: 7, Blocked By: Task 4
|
||||
|
||||
**References**:
|
||||
- `extend/base/common/service/stack/StackModeServiceBase.php` — applyMode 完整实现(第 106-178 行)
|
||||
- `app/common/service/stack/StackModeService.php` — 当前空类,在这里重写
|
||||
- `source/stack/stack.json` — managed_files 列表
|
||||
|
||||
**WHY Each Reference Matters**:
|
||||
- `StackModeServiceBase.php`: 必须理解 parent::applyMode() 的备份和复制逻辑,确保重写不丢失任何步骤
|
||||
- `StackModeService.php`: 要修改的文件
|
||||
- `stack.json`: managed_files 是清理逻辑的判断依据
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: 切换到 docker-dev 后 .docker-dev.env 出现
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. php think admin:stack:mode use docker-dev -f
|
||||
2. dir .docker-dev.env → 存在
|
||||
Evidence: .sisyphus/evidence/task-6-appear.txt
|
||||
|
||||
Scenario: 切回 default 后 .docker-dev.env 被自动删除
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. php think admin:stack:mode use default -f
|
||||
2. dir .docker-dev.env 2>nul → 不存在
|
||||
Evidence: .sisyphus/evidence/task-6-disappear.txt
|
||||
|
||||
Scenario: rollback 恢复
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. php think admin:stack:mode use docker-dev -f
|
||||
2. php think admin:stack:mode use default -f(删除 .docker-dev.env)
|
||||
3. php think admin:stack:mode rollback <backup_id>
|
||||
4. dir .docker-dev.env → 恢复存在
|
||||
Evidence: .sisyphus/evidence/task-6-rollback.txt
|
||||
```
|
||||
|
||||
**Commit**: YES - `feat(stack): 切换模式时自动删除多余的管理文件`
|
||||
- Files: `app/common/service/stack/StackModeService.php`
|
||||
|
||||
---
|
||||
|
||||
- [x] 7. 模式切换与 Docker 构建集成验证
|
||||
|
||||
**What to do**:
|
||||
- 端到端验证所有组件
|
||||
- 验证模式切换流程(含自动删除)
|
||||
- 验证 Docker 构建和启动
|
||||
- 验证 PHP 配置、Xdebug、服务连通性
|
||||
- 验证端口(8800/13306/16379/18888)
|
||||
- 发现问题则修复并重验证
|
||||
|
||||
**Recommended Agent Profile**: `deep`, Skills: [`ulthon-cli-reference`]
|
||||
|
||||
**Parallelization**: Wave 3, Blocks: F1-F4, Blocked By: Tasks 1-6
|
||||
|
||||
**References**:
|
||||
- `source/stack/README.md` — 模式切换 fallback 规则
|
||||
- `docker/run.sh` — 容器启动逻辑
|
||||
|
||||
**QA Scenarios**:
|
||||
```
|
||||
Scenario: 完整切换流程
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. copy Dockerfile Dockerfile.bak && copy docker-compose.yaml docker-compose.yaml.bak
|
||||
2. php think admin:stack:mode use docker-dev -f
|
||||
3. fc Dockerfile source\stack\docker-dev\Dockerfile → 一致
|
||||
4. fc docker-compose.yaml source\stack\docker-dev\docker-compose.yaml → 一致
|
||||
5. dir .docker-dev.env → 存在
|
||||
Evidence: .sisyphus/evidence/task-7-switch.txt
|
||||
|
||||
Scenario: Docker 构建和启动
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. copy .docker-dev.env .env
|
||||
2. docker compose build --no-cache → 成功
|
||||
3. docker compose up -d
|
||||
4. timeout /t 30 /nobreak >nul
|
||||
5. docker compose ps → 4 个 running/healthy
|
||||
Evidence: .sisyphus/evidence/task-7-build.txt
|
||||
|
||||
Scenario: PHP 配置和 Xdebug
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. docker compose exec ulthon_admin php -r "echo ini_get('opcache.enable');" → 0
|
||||
2. docker compose exec ulthon_admin php -r "echo ini_get('display_errors');" → 1
|
||||
3. docker compose exec ulthon_admin php -m | findstr xdebug → xdebug
|
||||
Evidence: .sisyphus/evidence/task-7-php.txt
|
||||
|
||||
Scenario: 连通性和端口
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. docker compose exec ulthon_admin php -r "$c=@fsockopen('mysql',3306); echo $c?'OK':'FAIL';" → OK
|
||||
2. docker compose exec ulthon_admin php -r "$c=@fsockopen('redis',6379); echo $c?'OK':'FAIL';" → OK
|
||||
3. curl -s -o nul -w "%%{http_code}" http://localhost:8800/admin → 200/302
|
||||
4. curl -s -o nul -w "%%{http_code}" http://localhost:18888/ → 200
|
||||
Evidence: .sisyphus/evidence/task-7-connect.txt
|
||||
|
||||
Scenario: 数据目录
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. dir docker-dev\mysql → 存在
|
||||
2. dir docker-dev\redis → 存在
|
||||
Evidence: .sisyphus/evidence/task-7-data.txt
|
||||
|
||||
Scenario: 切回 default + 清理
|
||||
Tool: Bash
|
||||
Steps:
|
||||
1. docker compose down
|
||||
2. php think admin:stack:mode use default -f
|
||||
3. dir .docker-dev.env 2>nul → 不存在
|
||||
4. copy Dockerfile.bak Dockerfile && copy docker-compose.yaml.bak docker-compose.yaml
|
||||
5. del *.bak .env
|
||||
6. git status → 无残留
|
||||
Evidence: .sisyphus/evidence/task-7-cleanup.txt
|
||||
```
|
||||
|
||||
**Commit**: NO (验证任务)
|
||||
|
||||
---
|
||||
|
||||
## Final Verification Wave (MANDATORY)
|
||||
|
||||
- [x] F1. **Plan Compliance Audit** — `oracle` — APPROVE
|
||||
Must Have [10/10] | Must NOT Have [9/9]
|
||||
|
||||
- [x] F2. **Code Quality Review** — `unspecified-high` — APPROVE (after P0/P1 fixes)
|
||||
HOSTPORT 3306 fix applied, backup_id protection added
|
||||
|
||||
- [x] F3. **Real Manual QA** — `unspecified-high` — APPROVE (atlas manual verification)
|
||||
Scenarios [6/6 pass]: mode list, switch docker-dev, file verification, switch default auto-delete, rollback restore, cleanup
|
||||
|
||||
- [x] F4. **Scope Fidelity Check** — `deep` — APPROVE (after git checkout restore)
|
||||
Tasks [6/6] | Contamination [CLEAN]
|
||||
|
||||
---
|
||||
|
||||
## Commit Strategy
|
||||
|
||||
- **Commit 1**: `feat(stack): 新增 docker-dev 开发模式`
|
||||
- Files: `source/stack/docker-dev/Dockerfile`, `source/stack/docker-dev/docker-compose.yaml`, `source/stack/docker-dev/.docker-dev.env`, `source/stack/stack.json`, `.gitignore`
|
||||
- **Commit 2**: `feat(stack): 切换模式时自动删除多余的管理文件`
|
||||
- Files: `app/common/service/stack/StackModeService.php`
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
### Verification Commands
|
||||
```bash
|
||||
php think admin:stack:mode list # 包含 docker-dev
|
||||
php think admin:stack:mode use docker-dev -f # 切换成功
|
||||
dir .docker-dev.env # 文件存在
|
||||
copy .docker-dev.env .env # 配置就绪
|
||||
docker compose up -d # 4 服务运行
|
||||
curl http://localhost:8800/admin # 可访问
|
||||
php think admin:stack:mode use default -f # 切回
|
||||
dir .docker-dev.env 2>nul # 文件已自动删除
|
||||
```
|
||||
|
||||
### Final Checklist
|
||||
- [ ] All "Must Have" present
|
||||
- [ ] All "Must NOT Have" absent
|
||||
- [ ] `docker compose config` 通过
|
||||
- [ ] 未修改 `docker/run.sh`
|
||||
- [ ] 未修改 `extend/base/`
|
||||
- [ ] `.example.env` 未被修改
|
||||
- [ ] 切回 default 时 `.docker-dev.env` 自动删除
|
||||
@@ -44,6 +44,7 @@
|
||||
- 前端:视图与脚本同名配对(`*.html` + 同名 `*.js`),并按模块维护 `_common.js`
|
||||
- 配套资源与多端代码:统一放在 `source/`;不影响现有 PHP/ThinkPHP 主工程运行与发布;目录约定与安全要求见 `source/README.md`(禁止提交构建产物、依赖目录等)
|
||||
- 部署栈模式:`source/stack/` 为模式文件统一目录(含 `default/` 与各模式目录);`default/` 必须与代码库默认行为一致;默认行为相关文件变更时需同步更新 `source/stack/default/` 对应文件
|
||||
- 命令执行环境:执行 `php think` 命令前,通过 `php think admin:stack:mode current` 检测当前模式;若为 `docker-dev`,所有 `php think` 命令前缀改为 `docker compose exec ulthon_admin`(如 `docker compose exec ulthon_admin php think tools:http:call`);其他模式(default/full/base-build)直接在宿主机执行 `php think`,不做转换
|
||||
- 接口:如果需要实现接口能力,需要利用框架的“页面接口同体机制”,框架支持直接所有“页面输出”改为“json输出”。
|
||||
- 风格:遵循项目命名规范与 PSR;格式化以仓库根目录 `.php-cs-fixer.php` 配置为准(不假设本机已安装工具)
|
||||
- 权限:基于 `auth` 注解生成节点与鉴权;以角色为中心管理(角色、角色权限、用户角色);命令行使用见技能:[ulthon-permission-cli](./.agents/skills/ulthon-permission-cli/SKILL.md)
|
||||
|
||||
37
source/stack/default/docker/run.sh
Normal file
37
source/stack/default/docker/run.sh
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 将代码中的nginx复制到nginx配置文件中
|
||||
cp /var/www/html/docker/nginx.conf /etc/nginx/sites-available/default
|
||||
ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
|
||||
|
||||
# 将代码中的php配置文件复制到php配置文件中
|
||||
cp /var/www/html/docker/zz-phprun.ini /usr/local/etc/php/conf.d
|
||||
cp /var/www/html/docker/zz-phpfpm.conf /usr/local/etc/php-fpm.d
|
||||
|
||||
|
||||
# 设置目录权限,确保挂载卷后依然有效
|
||||
mkdir -p /var/www/html/runtime && chmod -R 777 /var/www/html/runtime
|
||||
mkdir -p /var/www/html/public/storage && chmod -R 777 /var/www/html/public/storage
|
||||
mkdir -p /var/www/html/public/build && chmod -R 777 /var/www/html/public/build
|
||||
mkdir -p /var/www/html/storage && chmod -R 777 /var/www/html/storage
|
||||
mkdir -p /var/www/html/memoryspace && chown -R www-data:www-data /var/www/html/memoryspace
|
||||
|
||||
|
||||
# 运行redis
|
||||
# nohup redis-server --requirepass "" &
|
||||
|
||||
# 输出参数
|
||||
echo "参数为:$@"
|
||||
|
||||
# TODO:增加自动批量运行并阻塞的脚本,比如:group default ,会调用auto.sh的default的部分,最终阻塞,auth.sh的default部分,可能会运行一系列的命令,比如清空缓存,踢人下线,重置密码
|
||||
|
||||
if [ "$1" = "server" ] || [ "$1" = "" ]; then
|
||||
# 运行定时任务 TODO:以指定用户运行
|
||||
su - www-data -c "nohup php /var/www/html/think timer --local --quit &"
|
||||
# 运行nginx
|
||||
service nginx start
|
||||
# 运行php-fpm
|
||||
php-fpm
|
||||
else
|
||||
php "/var/www/html/""$@"
|
||||
fi
|
||||
6
source/stack/docker-dev/.dockerignore
Normal file
6
source/stack/docker-dev/.dockerignore
Normal file
@@ -0,0 +1,6 @@
|
||||
.git
|
||||
.sisyphus
|
||||
node_modules
|
||||
runtime
|
||||
docker-dev
|
||||
*.sock
|
||||
@@ -63,20 +63,8 @@ RUN composer dump-autoload
|
||||
# RUN install-php-extensions @composer
|
||||
|
||||
# Dev mode PHP config (overrides zz-phprun.ini)
|
||||
RUN echo '; Dev mode PHP config (overrides zz-phprun.ini)' > /usr/local/etc/php/conf.d/zzz-dev.ini && \
|
||||
echo 'opcache.enable = 0' >> /usr/local/etc/php/conf.d/zzz-dev.ini && \
|
||||
echo 'opcache.jit_buffer_size = 0' >> /usr/local/etc/php/conf.d/zzz-dev.ini && \
|
||||
echo 'display_errors = On' >> /usr/local/etc/php/conf.d/zzz-dev.ini && \
|
||||
echo 'error_reporting = E_ALL' >> /usr/local/etc/php/conf.d/zzz-dev.ini
|
||||
|
||||
# Xdebug dev config
|
||||
RUN echo '; Xdebug dev config' > /usr/local/etc/php/conf.d/zzz-xdebug.ini && \
|
||||
echo 'xdebug.mode = debug,develop' >> /usr/local/etc/php/conf.d/zzz-xdebug.ini && \
|
||||
echo 'xdebug.start_with_request = trigger' >> /usr/local/etc/php/conf.d/zzz-xdebug.ini && \
|
||||
echo 'xdebug.client_host = host.docker.internal' >> /usr/local/etc/php/conf.d/zzz-xdebug.ini && \
|
||||
echo 'xdebug.client_port = 9003' >> /usr/local/etc/php/conf.d/zzz-xdebug.ini && \
|
||||
echo 'xdebug.discover_client_host = true' >> /usr/local/etc/php/conf.d/zzz-xdebug.ini && \
|
||||
echo 'xdebug.idekey = DOCKER_DEV' >> /usr/local/etc/php/conf.d/zzz-xdebug.ini
|
||||
COPY docker/zzz-dev.ini /usr/local/etc/php/conf.d/zzz-dev.ini
|
||||
COPY docker/zzz-xdebug.ini /usr/local/etc/php/conf.d/zzz-xdebug.ini
|
||||
|
||||
VOLUME /var/www/html/runtime
|
||||
VOLUME /var/www/html/public/storage
|
||||
|
||||
41
source/stack/docker-dev/docker/run.sh
Normal file
41
source/stack/docker-dev/docker/run.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 将代码中的nginx复制到nginx配置文件中
|
||||
cp /var/www/html/docker/nginx.conf /etc/nginx/sites-available/default
|
||||
ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
|
||||
|
||||
# 将代码中的php配置文件复制到php配置文件中
|
||||
cp /var/www/html/docker/zz-phprun.ini /usr/local/etc/php/conf.d
|
||||
cp /var/www/html/docker/zz-phpfpm.conf /usr/local/etc/php-fpm.d
|
||||
|
||||
# 开发模式:覆盖生产PHP配置(Opcache、错误显示、Xdebug)
|
||||
cp /var/www/html/docker/zzz-dev.ini /usr/local/etc/php/conf.d
|
||||
cp /var/www/html/docker/zzz-xdebug.ini /usr/local/etc/php/conf.d
|
||||
|
||||
|
||||
# 设置目录权限,确保挂载卷后依然有效
|
||||
mkdir -p /var/www/html/runtime && chmod -R 777 /var/www/html/runtime
|
||||
mkdir -p /var/www/html/public/storage && chmod -R 777 /var/www/html/public/storage
|
||||
mkdir -p /var/www/html/public/build && chmod -R 777 /var/www/html/public/build
|
||||
mkdir -p /var/www/html/storage && chmod -R 777 /var/www/html/storage
|
||||
mkdir -p /var/www/html/memoryspace && chown -R www-data:www-data /var/www/html/memoryspace
|
||||
|
||||
|
||||
# 运行redis
|
||||
# nohup redis-server --requirepass "" &
|
||||
|
||||
# 输出参数
|
||||
echo "参数为:$@"
|
||||
|
||||
# TODO:增加自动批量运行并阻塞的脚本,比如:group default ,会调用auto.sh的default的部分,最终阻塞,auth.sh的default部分,可能会运行一系列的命令,比如清空缓存,踢人下线,重置密码
|
||||
|
||||
if [ "$1" = "server" ] || [ "$1" = "" ]; then
|
||||
# 运行定时任务 TODO:以指定用户运行
|
||||
su -www-data -c "nohup php /var/www/html/think timer --local --quit &"
|
||||
# 运行nginx
|
||||
service nginx start
|
||||
# 运行php-fpm
|
||||
php-fpm
|
||||
else
|
||||
php "/var/www/html/""$@"
|
||||
fi
|
||||
9
source/stack/docker-dev/docker/zzz-dev.ini
Normal file
9
source/stack/docker-dev/docker/zzz-dev.ini
Normal file
@@ -0,0 +1,9 @@
|
||||
; Dev mode PHP config (overrides zz-phprun.ini)
|
||||
opcache.enable = 1
|
||||
opcache.memory_consumption = 128
|
||||
opcache.validate_timestamps = 1
|
||||
opcache.revalidate_freq = 3
|
||||
opcache.interned_strings_buffer = 16
|
||||
opcache.max_accelerated_files = 20000
|
||||
display_errors = On
|
||||
error_reporting = E_ALL
|
||||
7
source/stack/docker-dev/docker/zzz-xdebug.ini
Normal file
7
source/stack/docker-dev/docker/zzz-xdebug.ini
Normal file
@@ -0,0 +1,7 @@
|
||||
; Xdebug dev config
|
||||
xdebug.mode = debug,develop
|
||||
xdebug.start_with_request = yes
|
||||
xdebug.client_host = host.docker.internal
|
||||
xdebug.client_port = 9003
|
||||
xdebug.discover_client_host = true
|
||||
xdebug.idekey = DOCKER_DEV
|
||||
@@ -4,7 +4,11 @@
|
||||
"Dockerfile",
|
||||
"docker-compose.yaml",
|
||||
".gitea/workflows/build-and-deploy.yml",
|
||||
".docker-dev.env"
|
||||
".docker-dev.env",
|
||||
".dockerignore",
|
||||
"docker/zzz-dev.ini",
|
||||
"docker/zzz-xdebug.ini",
|
||||
"docker/run.sh"
|
||||
],
|
||||
"modes": {
|
||||
"default": {
|
||||
|
||||
Reference in New Issue
Block a user