微昕·砚文档

本地开发

SMTP 邮件故障日志

注册、登录、绑定邮箱和密码找回的邮件投递失败统一输出 ERROR 级别的 smtp email delivery failed 后端日志。日志包含 host、port、encryption、脱敏 recipient 和 error,默认 CANVAS_LOG_LEVEL=info 即可看到,无需开启 debug。

error 保留 SMTP 状态码和服务器错误说明,并标记失败步骤:connect / connect_tls(连接)、greeting(服务器欢迎响应)、starttls、auth、mail_from、rcpt_to、data、write_body、finish_data 或 quit。日志不主动记录账号、密码、邮件标题、正文或验证码,并对错误中回显的这些值及其 Base64 编码做脱敏。对外 API 继续使用原有通用错误响应。

宿主机开发查看运行后端的终端;Docker 查看实际使用的 Compose 文件中的 backend 服务,例如:

docker compose -f docker-compose.deploy.yml logs --since=15m -f backend

本地构建和热更新开发分别将文件名换成 docker-compose.local.yml 或 docker-compose.dev.yml。代码修改后需要运行新构建的后端,旧容器不会自动增加这些日志。

Compose 公网资源地址

docker-compose.yml、docker-compose.dev.yml、docker-compose.local.yml、docker-compose.server.yml 和 docker-compose.deploy.yml 均将 .env 中的 CANVAS_PUBLIC_BASE_URL 传入后端。使用本地文件存储且上游模型需要读取参考素材时,将它设为上游能访问的 HTTPS 站点根地址(例如 https://canvas.example.com,不要附加 /api);存储设置中的公网访问地址优先于该环境变量。

修改后需要重新创建后端容器,单纯重启旧容器不会更新环境变量。未配置时保持空值并由资源请求强校验,不会自动采用容器内网地址;这项设置不放宽出站 SSRF 校验,也不应为此开放数据库或后端端口。只做本地界面开发且不向模型提交资源时可以不设置。部署后仍需验证真实资源 URL 能被目标供应商读取,健康检查不能替代该验证。

一键启动(Windows PowerShell)

在仓库根目录执行:

.\scripts\start-local.ps1

脚本会:

  • 使用 .local/project-workbench-debug 作为后端 SQLite 开发数据目录;
  • 创建 .local/cache/go-build 和 .local/cache/go-mod 缓存目录;
  • 首次启动时,如果 web/node_modules 不存在,执行 bun install --frozen-lockfile;
  • 打开两个 PowerShell 窗口,分别运行后端和前端;
  • 将前端 /api 请求代理到 http://127.0.0.1:8080。

启动后访问 http://localhost:3000。后端健康检查地址是 http://127.0.0.1:8080/api/health。

脚本使用固定的本地开发端口:前端 3000,后端 8080。如果端口被占用,脚本会先退出,不会关闭已有进程。请分别在两个开发窗口中按 Ctrl+C 停止服务。

如果 PowerShell 的执行策略阻止脚本运行,可以只对当前进程临时放行:

Set-ExecutionPolicy -Scope Process Bypass
.\scripts\start-local.ps1

手工启动

后端:

mkdir -p .local/project-workbench-debug .local/cache/go-build .local/cache/go-mod
cd backend
CANVAS_BACKEND_ADDR=127.0.0.1:8080 \
CANVAS_BACKEND_DATA_DIR=../.local/project-workbench-debug \
GOCACHE=../.local/cache/go-build \
GOMODCACHE=../.local/cache/go-mod \
go run ./cmd/server

前端另开终端:

cd web
bun install --frozen-lockfile
bun run dev

web/ 只使用 bun.lock。不要用 pnpm 或 npm 往同一套 node_modules 里再装一遍。

前端默认监听 0.0.0.0:3000,Vite 将 /api 和 OAuth 回调代理到 127.0.0.1:8080。如需修改代理目标,可设置 VITE_API_PROXY_TARGET。

时间线字幕转写(whisper.cpp)

时间线“字幕转写”由本地 whisper.cpp server 执行:后端将片段音频预处理为 16k mono wav 后,POST 到 CANVAS_WHISPER_BASE_URL/inference(whisper server 原生接口,response_format=verbose_json)。未配置该地址时,转写任务会立即明确失败,提示“撰写失败未配置本地转写服务”。

安装 whisper-server

brew install whisper-cpp

下载模型

仓库脚本将模型放在 .local/whisper-models/(已被 .gitignore 忽略)。多语言模型(含中文)用 ggml-base.bin(约 141MB);网络受限时可用 aifasthub 镜像:

mkdir -p .local/whisper-models
curl -fL -o .local/whisper-models/ggml-base.bin \
  https://aifasthub.com/ggerganov/whisper.cpp/resolve/main/ggml-base.bin

启动服务

scripts/start-whisper-local.sh

脚本默认以 ggml-base.bin 监听 127.0.0.1:8082(-l auto 自动识别语言)。需要换模型或端口时:WHISPER_MODEL=ggml-small.bin WHISPER_PORT=8083 scripts/start-whisper-local.sh。

让后端指向该服务

后端不读取 .env 文件,环境变量必须由启动 shell 注入(在手工启动命令基础上追加):

cd backend
CANVAS_BACKEND_DATA_DIR=../.local/project-workbench-debug \
CANVAS_WHISPER_BASE_URL=http://127.0.0.1:8082 \
go run ./cmd/server

验证

# 服务就绪:返回 200/404 即可
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8082/
# 冒烟:20 秒语音 → verbose_json 字幕段
curl -s -X POST http://127.0.0.1:8082/inference \
  -F 'file=@sample.wav' -F 'response_format=verbose_json'

Docker 开发

需要容器化热更新时,在仓库根目录执行:

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 调整宿主机端口。

On this page