Files
codex-proxy-rs/docs/project-layout-restructure.md
T
2026-07-01 17:13:00 +08:00

8.5 KiB

Project Layout Restructure

背景

项目目录已按 Sub2API 的边界收敛:

  • backend/ 承载后端应用、后端构建元信息和后端测试。
  • frontend/ 承载前端应用。
  • deploy/ 承载 Docker、Compose、部署脚本和部署示例配置。

根目录只保留仓库级入口和文档,不再承载后端源码、前端源码或具体部署实现。

完成后结构

codex-proxy-rs/
├── backend/
│   ├── Cargo.toml
│   ├── Cargo.lock
│   ├── build/
│   │   ├── build.rs
│   │   └── VERSION
│   ├── rust-toolchain.toml
│   ├── src/
│   └── tests/
├── frontend/
│   ├── package.json
│   ├── pnpm-lock.yaml
│   ├── pnpm-workspace.yaml
│   ├── vite.config.ts
│   └── src/
├── deploy/
│   ├── Dockerfile
│   ├── docker-compose.yml
│   ├── config.example.yaml
│   └── README.md
├── docs/
├── README.md
└── .github/

说明:

  • backend/build/VERSION 是唯一的源码默认版本文件。它对应 Sub2API 的 backend/cmd/server/VERSION,但本项目的 Rust 入口仍保留在 backend/src/main.rs,所以版本元信息归入 backend/build/。
  • backend/build/build.rs 读取 CPR_VERSION,否则读取 backend/build/VERSION,最后才回落到 CARGO_PKG_VERSION。
  • frontend/ 替代原 web/。前端只负责展示后端返回的版本、构建类型、部署类型和更新进度。
  • deploy/ 替代根目录里的部署文件归属。根目录只保留仓库级入口和文档,不承载具体部署实现。
  • 测试代码继续放在测试目录,禁止放入 backend/src。

路径映射

原路径 新路径 备注
src/ backend/src/ Rust 后端源码。
tests/ backend/tests/ Rust 集成测试,仍在测试目录,不进入源码目录。
Cargo.toml backend/Cargo.toml 后端 package manifest。
Cargo.lock backend/Cargo.lock 后端锁文件,随后端移动。
build.rs backend/build/build.rs 后端构建脚本。
VERSION backend/build/VERSION 后端应用版本源。
rust-toolchain.toml backend/rust-toolchain.toml 后端工具链配置。
web/ frontend/ 前端应用。
Dockerfile deploy/Dockerfile 生产镜像构建入口。
docker-compose.yml deploy/docker-compose.yml Docker 部署入口。
config.yaml deploy/config.example.yaml 根目录不保留本地运行配置。

Cargo 组织方式

优先采用 Sub2API 风格:后端是自包含子项目。

backend/
├── Cargo.toml
├── Cargo.lock
├── build/
│   ├── build.rs
│   └── VERSION
├── src/
└── tests/

后续命令从:

cargo test --test main admin::system --locked
cargo clippy --all-targets --all-features --locked -- -D warnings

调整为:

cargo test --manifest-path backend/Cargo.toml --test main admin::system --locked
cargo clippy --manifest-path backend/Cargo.toml --all-targets --all-features --locked -- -D warnings

如果后续需要根目录统一调度,可以再加一个很薄的 root workspace Cargo.toml,但不要让根目录重新成为后端版本源。

根目录 target/ 不是项目构建目标目录。迁移后后端构建产物位于 backend/target/;如果本地编辑器或 rust-analyzer 在根目录生成 target/flycheck*,它只是本地检查临时产物,可以直接删除,且已被 .gitignore 忽略。

前端迁移点

web/ 已迁移到 frontend/,同步点:

  • .github/workflows/release.yml 中所有 pnpm --dir web ... 改为 pnpm --dir frontend ...。
  • Dockerfile 中所有 web/package.json、web/pnpm-lock.yaml、web/dist 改为 frontend/...。
  • README、部署文档和开发命令里的 web 改为 frontend。
  • 前端 API 类型和更新弹窗不做业务重写,只做路径迁移。

部署迁移点

deploy/ 负责部署相关文件:

  • deploy/Dockerfile
  • deploy/docker-compose.yml
  • deploy/config.example.yaml
  • deploy/README.md

Docker 构建上下文仍建议使用仓库根目录:

docker build -f deploy/Dockerfile -t codex-proxy-rs .

这样 Dockerfile 可以同时访问 backend/ 和 frontend/,避免把构建上下文拆散。

Compose 文件迁移到 deploy/ 后,默认挂载路径随 Compose 文件落在 deploy/ 目录,保持部署文件和部署状态集中;需要接入外部配置或数据目录时,通过环境变量覆盖:

services:
  codex-proxy-rs:
    volumes:
      - ${CPR_CONFIG_FILE:-./config.yaml}:/app/config.yaml:ro
      - ${CPR_DATA_DIR:-./data}:/app/data
      - ${CPR_LOG_DIR:-./logs}:/app/logs

使用 deploy/config.example.yaml 作为样例,运行时配置由用户复制为 deploy/config.yaml 或通过 CPR_CONFIG_FILE 挂载提供。

发布链路调整

发布版本必须只有一个来源:

  1. Git tag,例如 v0.1.1。
  2. CI 去掉前缀 v,得到 0.1.1。
  3. CI 写入 backend/build/VERSION。
  4. CI 构建后端时传入:
    • CPR_VERSION=0.1.1
    • CPR_GIT_SHA=<sha>
    • CPR_BUILD_TIME=<utc>
    • CPR_BUILD_TYPE=release
  5. backend/build/build.rs 将这些值注入二进制。
  6. 后端 /api/admin/system/version 和 /api/admin/system/check-updates 使用二进制内的版本值。
  7. 前端只展示后端返回的数据,不做版本映射。

需要同步修改:

  • .github/workflows/release.yml
  • deploy/Dockerfile
  • backend/build/build.rs
  • backend/src/admin/system/routes.rs
  • backend/tests/admin/system/mod.rs

Dockerfile 调整

目标 Dockerfile 阶段:

FROM node:24-bookworm-slim AS frontend-builder
WORKDIR /app/frontend
COPY frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY frontend ./
RUN pnpm build

FROM rust:1.95-bookworm AS backend-builder
WORKDIR /app/backend
COPY backend/Cargo.toml backend/Cargo.lock ./
COPY backend/build ./build
COPY backend/src ./src
COPY --from=frontend-builder /app/frontend/dist ./web/dist
RUN cargo build --release --locked --bin codex-proxy-rs

FROM debian:bookworm-slim AS runtime
WORKDIR /app
ENV CPR_DEPLOYMENT_MODE=docker
COPY --from=backend-builder /app/backend/target/release/codex-proxy-rs /usr/local/bin/codex-proxy-rs
COPY --from=frontend-builder /app/frontend/dist ./web/dist
CMD ["codex-proxy-rs"]

注意:

  • Docker runtime 镜像不设置 CPR_VERSION,避免运行时环境变量成为第二版本源。
  • Docker runtime 仍只包含主服务,不恢复 updater sidecar。
  • deploy/Dockerfile 的构建上下文应保持仓库根目录。

迁移记录

本次迁移执行项:

  1. 新建 backend/,用 git mv 移动 src/、tests/、Cargo.toml、Cargo.lock、rust-toolchain.toml,并将 build.rs、VERSION 归入 backend/build/。
  2. 新建 frontend/,用 git mv web frontend。
  3. 新建 deploy/,用 git mv Dockerfile deploy/Dockerfile、git mv docker-compose.yml deploy/docker-compose.yml,并移动部署样例配置。
  4. 修改 .github/workflows/release.yml 的工作目录、构建路径、打包路径和 Dockerfile 路径。
  5. 修改 deploy/Dockerfile 的 COPY 路径。
  6. 修改 .dockerignore 和 .gitignore,使用 frontend/node_modules、frontend/dist、backend/target。
  7. 修改文档和 README 中的开发、测试、构建命令。

验收命令

迁移完成后至少运行:

cargo test --manifest-path backend/Cargo.toml --test main admin::system --locked
cargo clippy --manifest-path backend/Cargo.toml --all-targets --all-features --locked -- -D warnings
pnpm --dir frontend build
docker build -f deploy/Dockerfile -t codex-proxy-rs:latest .
docker compose -f deploy/docker-compose.yml config
git diff --check

如果保留 root workspace,则还需要确认:

cargo metadata --format-version 1

输出中不能重新出现旧的 updater binary,也不能把根 VERSION 当成版本源。

完成标准

  • 顶层不再有 src/ 和 web/。
  • 后端源码、测试和版本源都归属 backend/。
  • 前端应用归属 frontend/。
  • Dockerfile、Compose 和部署样例归属 deploy/。
  • backend/build/VERSION 是唯一源码默认版本文件。
  • 发布 tag、release asset、Docker image label、后端 /version、前端更新弹窗显示同一个版本。
  • Docker 部署仍是单主服务模式,不恢复 updater sidecar。