部署运维
推荐部署主线
长期部署拓扑应继续收敛到:
Nginx
-> Laravel API
-> React SPA 静态资源
MariaDB
Redis
Analysis Worker
Docker Compose
前端迁移说明
仓库在 Nuxt 到 SPA 迁移期曾包含两条前端线。自 v1.4.3 起,React/Vite SPA 已成为规范 frontend/ 目录,旧 Nuxt/Vue 实现已从活跃运行时目录中移除。
历史 v1.1 迁移工作保留在路线图文档中,但部署运维应使用下面的 v1.4.3 规范布局。
Laravel 运行要求
- Laravel 继续作为统一后端入口
- 数据库初始化使用 migration / seeder
- 旧轻量 PHP 实现仅作为
backend/legacy-lightweight/中的历史参考
数据库初始化
服务启动后,推荐执行:
docker compose exec php php /var/www/html/artisan migrate --seed --force
重置数据库可执行:
docker compose exec php php /var/www/html/artisan migrate:fresh --seed --force
Analysis Worker 与 Redis 边界
当前运行假设:
analysis_jobs已落在 MariaDB- Redis 列表
ANALYSIS_JOB_REDIS_QUEUE是 Worker 的异步交接边界 analysis-worker处理分析工作负载- 默认 YOLO 模型路径为
analysis-worker/models/uprc2018/best.pt
运维上可理解为:
- Laravel 创建并查询任务
- Laravel 在数据库持久化成功后,将排队任务 id 推入 Redis
- Analysis Worker 消费 Redis,执行受支持任务,并通过 Laravel API 回写结果
默认队列名为:
REDIS_PREFIX=
ANALYSIS_JOB_REDIS_QUEUE=ocean:analysis-jobs:queued
该 Worker 交接路径中 REDIS_PREFIX 应保持为空,以确保 Laravel 与 analysis-worker 读写同一个 Redis 列表名。
如果创建任务时 Redis 短暂不可用,数据库中的持久任务记录仍会保留。运维人员可在 Redis 恢复后重试失败任务或重新入队。
常用验证命令
治理 actor 上下文
curl -s -X POST http://127.0.0.1:8080/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"password"}'
curl -s -H 'X-Ocean-Actor-Id: 3' http://127.0.0.1:8080/api/governance/me
curl -s http://127.0.0.1:8080/api/governance/roles
在 v1.4.0 中,SPA 通过 POST /api/auth/login 登录,并在受保护写路由中发送 Authorization: Bearer <token>。X-Ocean-Actor-Id 是内部身份注入桥接,不是公开认证机制;它仅在过渡期作为非 SPA 工具的内部路径保留,用户发起的受保护写操作需要 bearer token。
Analysis Worker 回调在引入真正 Worker 凭证前使用内部桥接请求头:
curl -s -H 'X-Ocean-Worker: ocean-analysis-worker' http://127.0.0.1:8080/api/analysis-jobs
审计事件
curl -s http://127.0.0.1:8080/api/audit-events?page_size=20
curl -s 'http://127.0.0.1:8080/api/audit-events?resource_type=analysis_job'
可通过审计事件验证任务开始/提交、样本结果创建、异常解决、分析作业生命周期推进等高价值动作。
设置与用户管理
以 admin 登录后,保存 bearer token 并通过 API 验证 v1.4.1 治理页面:
TOKEN="$(
curl -s -X POST http://127.0.0.1:8080/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"password"}' \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["data"]["token"])'
)"
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8080/api/profile
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8080/api/settings
curl -s -H "Authorization: Bearer $TOKEN" 'http://127.0.0.1:8080/api/users?page_size=20'
curl -s -X PATCH http://127.0.0.1:8080/api/settings \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"language":"zh-Hans","display_density":"comfortable","default_workspace_tab":"settings"}'
验证用户、个人资料和设置变更的审计覆盖:
curl -s 'http://127.0.0.1:8080/api/audit-events?resource_type=user&page_size=20'
首页摘要
curl -s http://127.0.0.1:8080/api/dashboard/summary
巡检任务
curl -s http://127.0.0.1:8080/api/inspection-tasks
Laravel API 路由
docker exec ocean-php php /var/www/html/artisan route:list --path=api
迁移状态
docker exec ocean-php php /var/www/html/artisan migrate:status
分析队列深度
docker exec ocean-redis redis-cli LLEN ocean:analysis-jobs:queued
文档站部署
文档站位于 website/,使用 Docusaurus,并独立部署到 GitHub Pages。
交付原则:
- 文档构建与业务服务构建分离
- 文档可以独立发布
- 站点默认语言为英文,简体中文通过 i18n 提供
默认 SPA 静态托管
默认 Compose 路径现在服务 React/Vite 工作台前端:
frontend服务从docker/frontend/Dockerfile构建- SPA 镜像在
80端口提供静态资源,并通过 fallback 返回index.html - 顶层 Nginx 将
/代理到 SPA 容器 - 顶层 Nginx 将
/api/路由到 Laravel / PHP 入口
相关文件包括:
docker/nginx/default.confdocker/frontend/Dockerfiledocker/frontend/nginx.confdocker/compose.local.yml- 根目录
docker-compose.yml兼容 include
早期 Nuxt 实现已从活跃仓库布局中移除。历史背景保留在文档与 git 历史中。
默认本地 Compose 中的异步分析服务命名为 analysis-worker,源码目录也统一为 analysis-worker/。
v1.4.2 生产镜像方向
下一步部署加固应将主体 Web 应用打包为一个生产镜像,同时继续隔离基础设施与分析工作负载。
推荐生产拓扑:
app
- Nginx
- PHP-FPM
- Laravel API
- 构建后的 React/Vite SPA
db
redis
analysis-worker
目标 app 镜像应替代当前生产路径中对独立 frontend、nginx、php 容器的需求。该镜像不应包含 MariaDB、Redis 或分析 Worker 进程。
目标镜像应通过多阶段流程构建:
- 在
frontend/中执行pnpm install --frozen-lockfile与pnpm run build - 以
--no-dev --optimize-autoloader安装后端 Composer 依赖 - 将 Laravel 源码、vendor 依赖和 SPA 构建产物复制到运行时镜像
- 通过 entrypoint 或 supervisor 在同一个 app 容器中运行 Nginx 与 PHP-FPM
生产 Nginx 应直接服务 SPA 静态文件并提供 history fallback,同时将 /api/ 通过本地 PHP-FPM 路由到 Laravel public/index.php。运行时配置必须来自环境变量,不要把 .env 密钥烘焙进镜像。
生产路径将服务名与源码目录统一为 analysis-worker,因为该服务的产品职责是异步分析执行、图像 / 模型推理和结果回写。Python 是实现语言,不应成为面向部署的产品角色名。
存储需要单独处理:Laravel public / uploads storage 应保持持久化;当图像分析作业需要读取本地文件时,应按当前 OCEAN_STORAGE_ROOT 语义挂载给 analysis-worker。
迁移应继续作为显式部署步骤,例如:
docker compose -f docker/compose.prod.yml run --rm app php artisan migrate --force
除非发布流程明确采用该策略,否则不要在每次 Web 容器启动时静默执行迁移。app 镜像支持显式开关 OCEAN_RUN_MIGRATIONS=true,供明确希望启动时迁移的受控环境使用。
v1.4.3 仓库布局方向
v1.4.3 已在不改变 v1.4.2 已引入的产品运行职责前提下,规范文件位置。
当前活跃布局为:
backend/ Laravel API
frontend/ 活跃 React/Vite SPA
analysis-worker/ 由 Python 实现的异步分析 Worker
docker/ Compose、Nginx、app 镜像和 worker 镜像资产
website/ Docusaurus 文档站
旧 Nuxt/Vue 实现不再占用活跃 frontend/ 路径。历史背景保留在文档与 git 历史中,而不是继续保留完整可运行应用。过时的 SPA Compose 示例已删除。
根目录 Compose 文件已最小化。优先使用 docker/compose.local.yml 与 docker/compose.prod.yml 这类明确路径;根目录 docker-compose.yml 仅作为本地上手兼容 include 保留。
v1.4.4 发布镜像推送
发布 tag 现在会推送生产拓扑所需的可部署镜像组合:
app:Nginx + PHP-FPM + Laravel API + 构建后的 React/Vite SPAanalysis-worker:异步分析、图像 / 模型推理和结果回写运行时
MariaDB 与 Redis 继续作为独立有状态服务,不包含在发布镜像中。
GitHub release 会推送到 GitHub Container Registry:
ghcr.io/<owner>/<repo>/app:<release-tag>
ghcr.io/<owner>/<repo>/app:latest
ghcr.io/<owner>/<repo>/analysis-worker:<release-tag>
ghcr.io/<owner>/<repo>/analysis-worker:latest
CNB tag release 会将同一组镜像推送到仓库 slug 下的 CNB Docker 制品库:
$CNB_DOCKER_REGISTRY/$CNB_REPO_SLUG/app:<release-tag>
$CNB_DOCKER_REGISTRY/$CNB_REPO_SLUG/app:latest
$CNB_DOCKER_REGISTRY/$CNB_REPO_SLUG/analysis-worker:<release-tag>
$CNB_DOCKER_REGISTRY/$CNB_REPO_SLUG/analysis-worker:latest
生产上线应优先使用不可变发布 tag。latest 只作为冒烟验证或明确希望跟随最新发布的受控环境便利指针。
后端开发 Docker 配置路径为 docker/backend/。本地 Compose 服务仍可命名为 php 以兼容既有命令,但新增文件路径引用应使用 docker/backend/,不要再使用旧的 docker/php/ 名称。
长期不推荐的方向
项目不应继续把 Nuxt SSR / Nitro 视作长期部署主线,因为:
- 它对内部管理工作台的收益有限
- 常驻 Node 运行时会增加部署与排障复杂度
- 文档、工作台 UI 与 API 的分层在 SPA + Laravel 下更清晰