diff --git a/.env.example b/.env.example index 2eb210a50..2c6bec71f 100644 --- a/.env.example +++ b/.env.example @@ -39,6 +39,9 @@ CANVAS_UPDATER_SOCKET_DIR=/run/open-ai-canvas-updater # CANVAS_REDIS_DATA_PATH=./redis-data # 宿主机访问端口;本项目使用 7380 以避免与同机其它工程(默认 3000)冲突 # CANVAS_HTTP_PORT=7380 +# 源码热更新编排(docker-compose.dev.yml)的宿主机端口;默认前端 7380、后端 7381(仅绑 127.0.0.1) +# CANVAS_WEB_HOST_PORT=7380 +# CANVAS_BACKEND_HOST_PORT=7381 # 后端日志:info 级别不输出成功的查询请求与 Agent 流式事件;排障时临时改为 debug。 # CANVAS_LOG_LEVEL=info diff --git a/AGENTS.md b/AGENTS.md index d6b60e4a7..781dab196 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -190,18 +190,21 @@ cd web && bun run dev | 场景 | 前端 | 后端 | | --- | --- | --- | | 本地开发(宿主机) | **7380** | **7381** | -| Docker(宿主机映射) | **7380** → 容器 3000 | 不暴露(容器内仍 8080) | +| Docker 本地构建(`docker-compose.yml`、`docker-compose.local.yml`) | **7380** → 容器 3000 | 不暴露(容器内仍 8080) | +| Docker 源码热更新(`docker-compose.dev.yml`) | **7380** → 容器 7380(vite 容器) | **7381**(仅绑 `127.0.0.1`)→ 容器 8080 | -容器内部端口保持上游原样(nginx `listen 3000`、后端 `:8080`),以减小与上游的差异面。改端口时必须同步: +容器内部端口保持上游原样(nginx `listen 3000`、后端 `:8080`),以减小与上游的差异面;只有 `docker-compose.dev.yml` 的 web 容器例外,它跑的是本仓库 `web/package.json` 的 vite dev server,容器内外统一 7380。改端口时必须同步: - `web/package.json` — `dev` / `start` 的 `--port` - `web/vite.config.ts` — `apiProxyTarget` 默认值 -- `backend/cmd/server/main.go` — `CANVAS_BACKEND_ADDR` 默认值 +- `backend/cmd/server/main.go` — `CANVAS_BACKEND_ADDR` 默认值 `127.0.0.1:7381` - `scripts/start-local.ps1` — 后端地址、代理目标、提示文案 -- `docker-compose.yml`、`docker-compose.local.yml` — 宿主机端口映射与 `CANVAS_CORS_ORIGINS` -- `.env.example` — `CANVAS_CORS_ORIGINS`、`CANVAS_HTTP_PORT` +- `docker-compose.yml`、`docker-compose.local.yml`、`docker-compose.dev.yml` — 宿主机端口映射与 `CANVAS_CORS_ORIGINS` +- `.env.example` — `CANVAS_CORS_ORIGINS`、`CANVAS_HTTP_PORT`、`CANVAS_WEB_HOST_PORT` / `CANVAS_BACKEND_HOST_PORT` - `README.md` 快速开始 +`backend/cmd/server/main.go` 的 `CANVAS_BACKEND_ADDR` 默认值(`127.0.0.1:7381`)是本仓库对上游唯一的一行端口偏离,容器内仍由 `backend/Dockerfile` 与各 Compose 显式注入上游 `:8080`。合并上游后必须检查这一行没有被改回 `:8080`,否则 `go run ./cmd/server` 会监听 8080,而前端仍按 7381 代理。 + `docker-compose.deploy.yml` / `docker-compose.server.yml` 与 `scripts/install-server*.sh` 面向独立服务器部署,保留上游的 3000 默认值,不做本地化改动。 `scripts/launch-canvas.ps1` 是上游维护者的个人脚本(硬编码 `D:\yingce\...`、`Administrator`、cloudflared 隧道),在本机不可用,**保持原样不要改**。 diff --git a/README.md b/README.md index 4ead3711a..5525570ce 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ bun run dev 打开 。首次使用时注册管理员账号,并在设置中配置模型渠道。前端默认将 `/api` 代理到 `http://127.0.0.1:7381`;如需修改代理目标,可设置 `VITE_API_PROXY_TARGET`。 -> **本项目端口约定**:本地开发使用前端 **7380** / 后端 **7381**,Docker 宿主机端口为 **7380**(容器内仍为上游默认的 3000/8080)。这样可与同机上的 `infinite-canvas`、`open-ai-canvas` 等工程并存。详见 [AGENTS.md](./AGENTS.md) 的「本项目附加约定」。 +> **本项目端口约定**:本地开发与 Docker 宿主机使用前端 **7380** / 后端 **7381**(容器内后端仍为上游默认的 `8080`,本地构建编排的 nginx 容器内为 `3000`)。这样可与同机上的 `infinite-canvas`、`open-ai-canvas` 等工程并存。详见 [AGENTS.md](./AGENTS.md) 的「本项目附加约定」。 Windows PowerShell 用户可在仓库根目录执行: @@ -135,7 +135,7 @@ LOCAL_UID=$(id -u) LOCAL_GID=$(id -g) \ docker compose -f docker-compose.local.yml up -d --build ``` -热更新开发默认前端端口为 `3000`、后端端口为 `8080`;端口冲突时可通过 `CANVAS_WEB_HOST_PORT` 和 `CANVAS_BACKEND_HOST_PORT` 覆盖。本地构建编排只暴露 web 的 `3000`,后端留在容器网络内,不安装 Host Updater。 +热更新开发默认前端端口为 `7380`、后端端口为 `7381`(后端在容器内仍监听上游的 `8080`);端口冲突时可通过 `CANVAS_WEB_HOST_PORT` 和 `CANVAS_BACKEND_HOST_PORT` 覆盖。本地构建编排只暴露 web 的 `7380`(容器内 nginx 为上游的 `3000`),后端留在容器网络内,不安装 Host Updater。 更多本地开发说明(包括时间线字幕转写)见[本地开发文档](docs/content/docs/backend/local-development.mdx)。 diff --git a/backend/cmd/server/fork_env.go b/backend/cmd/server/fork_env.go index ec876a78a..28b9f8588 100644 --- a/backend/cmd/server/fork_env.go +++ b/backend/cmd/server/fork_env.go @@ -1,5 +1,5 @@ -// 本项目附加文件(fork 专属):不改上游 main.go,达到同样的启动行为。 -// 独立成一个文件后,上游对同目录 main.go 的任何改动都不会再与本文件冲突。 +// 本项目附加文件(fork 专属):只补启动期的 .env 加载与诊断,不改上游 main.go 的主体。 +// 独立成一个文件后,上游对同目录 main.go 的改动基本不会再与本文件冲突。 package main import ( @@ -13,10 +13,11 @@ import ( func init() { config.LoadDotEnv() - // 本地开发默认绑定 127.0.0.1:7381(见 AGENTS.md「本项目附加约定」)。 - // 显式配置优先,例如 Compose 注入的 CANVAS_BACKEND_ADDR=":8080" 不会被覆盖。 - if strings.TrimSpace(os.Getenv("CANVAS_BACKEND_ADDR")) == "" { - _ = os.Setenv("CANVAS_BACKEND_ADDR", "127.0.0.1:7381") + // 监听地址的默认值在 main.go(127.0.0.1:7381,见 AGENTS.md「本项目附加约定」), + // 容器内由 Dockerfile / Compose 显式注入 :8080;这里不再改写环境变量。 + addr := strings.TrimSpace(os.Getenv("CANVAS_BACKEND_ADDR")) + if addr == "" { + addr = "127.0.0.1:7381 (main.go default)" } // 启动诊断:确认 .env / 环境变量已被读到,避免误用空 DATABASE_URL 时的静默回退。 @@ -24,5 +25,5 @@ func init() { if strings.TrimSpace(os.Getenv("DATABASE_URL")) != "" { dbURLState = "set" } - log.Printf("fork-env: CANVAS_BACKEND_ADDR=%s, DATABASE_URL=%s", os.Getenv("CANVAS_BACKEND_ADDR"), dbURLState) + log.Printf("fork-env: CANVAS_BACKEND_ADDR=%s, DATABASE_URL=%s", addr, dbURLState) } diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index 5058017a6..34d3a0588 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -74,7 +74,9 @@ func run(ctx context.Context) error { } repo := repository.New(db) - addr := env("CANVAS_BACKEND_ADDR", ":8080") + // 本项目宿主机默认监听 127.0.0.1:7381(见 AGENTS.md「本项目附加约定」); + // 容器内由 backend/Dockerfile 与各 Compose 显式注入 :8080。 + addr := env("CANVAS_BACKEND_ADDR", "127.0.0.1:7381") svc := service.New(repo, dataDir) if updaterToken := strings.TrimSpace(os.Getenv("CANVAS_UPDATER_TOKEN")); updaterToken != "" { svc.ConfigureUpdateManager(updaterclient.New(env("CANVAS_UPDATER_SOCKET", "/run/open-ai-canvas-updater/updater.sock"), updaterToken)) diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 59e2451da..7498fa00f 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -52,7 +52,8 @@ services: bind: create_host_path: false ports: - - "127.0.0.1:${CANVAS_BACKEND_HOST_PORT:-8080}:8080" + # 本项目宿主机端口为 7381(见 AGENTS.md「本项目附加约定」);容器内保持上游的 8080。 + - "127.0.0.1:${CANVAS_BACKEND_HOST_PORT:-7381}:8080" init: true web: @@ -69,7 +70,8 @@ services: - web-node-modules:/workspace/web/node_modules - web-bun-cache:/root/.bun/install/cache ports: - - "${CANVAS_WEB_HOST_PORT:-3000}:3000" + # vite dev server 沿用本项目的 7380(web/package.json 的 --port),宿主机映射同一端口。 + - "${CANVAS_WEB_HOST_PORT:-7380}:7380" depends_on: - backend init: true diff --git a/docs/content/docs/backend/local-development.mdx b/docs/content/docs/backend/local-development.mdx index d94b3913e..bc833349b 100644 --- a/docs/content/docs/backend/local-development.mdx +++ b/docs/content/docs/backend/local-development.mdx @@ -136,4 +136,4 @@ LOCAL_UID=$(id -u) LOCAL_GID=$(id -g) \ docker compose -f docker-compose.dev.yml up --build ``` -Docker 开发编排也使用 `.local/project-workbench-debug`,并默认暴露前端 `3000` 和后端 `8080`。端口冲突时,可通过 `CANVAS_WEB_HOST_PORT` 和 `CANVAS_BACKEND_HOST_PORT` 调整宿主机端口。 +Docker 开发编排也使用 `.local/project-workbench-debug`,并默认暴露前端 `7380` 和后端 `7381`(后端在容器内仍监听上游的 `8080`)。端口冲突时,可通过 `CANVAS_WEB_HOST_PORT` 和 `CANVAS_BACKEND_HOST_PORT` 调整宿主机端口。 diff --git a/docs/content/docs/progress/pending-test.mdx b/docs/content/docs/progress/pending-test.mdx index 97922a591..2a503f2b4 100644 --- a/docs/content/docs/progress/pending-test.mdx +++ b/docs/content/docs/progress/pending-test.mdx @@ -5,6 +5,13 @@ description: 当前项目已实现功能的手工验证清单与未确认边界 # 待测试 +## 本地端口约定对齐(dev 编排与后端默认监听) + +- 已实现:`docker-compose.dev.yml` 宿主机端口改为 `${CANVAS_WEB_HOST_PORT:-7380}:7380`(vite 容器内外统一 7380,与 `web/package.json` 一致)和 `127.0.0.1:${CANVAS_BACKEND_HOST_PORT:-7381}:8080`,与本项目 7380/7381 约定及该文件的 `CANVAS_CORS_ORIGINS` 对齐。同步更新 `README.md`、`docs/content/docs/backend/local-development.mdx`、`.env.example`、`AGENTS.md` 端口清单。 +- 已实现:`backend/cmd/server/main.go` 的 `CANVAS_BACKEND_ADDR` 默认值改为 `127.0.0.1:7381`(本仓库对上游唯一的一行端口偏离),`backend/cmd/server/fork_env.go` 不再重复注入、只保留 `.env` 加载与启动诊断;容器内仍由 `backend/Dockerfile` 与各 Compose 显式注入 `:8080`。 +- 已验证:用本地 `yaml` 依赖解析三个本地编排文件,端口映射为 `docker-compose.yml` / `docker-compose.local.yml` 的 `7380:3000`,`docker-compose.dev.yml` 的 `7380:7380` 与 `7381:8080`;`cd backend && go test ./cmd/server/...` 通过。 +- [ ] 未验证:本机无 Docker,未实际启动 `docker-compose.dev.yml`;需在有 Docker 的机器确认前端 7380 可访问、`/api` 经容器内 `http://backend:8080` 代理正常。 + ## 图片与视频电商出品工作室 - 已实现:`/toolbox/image` 与 `/toolbox/video` 保留紧凑工作区入口,移除顶部品牌介绍区;提供创作流程条、重置入口、快捷出品目标和工具选择弹窗。弹窗桌面五列,961px 以下四列、768px 以下两列;选择工具后空提示词自动套用首个预设,已有内容可通过预设入口追加或替换。