使用Docker Compose部署Workbuddy2api-panel进行反代的踩坑记录

Workbuddy2api-panel是Sliverkiss/workbuddy2api的增强分支,是一个自托管的CodeBuddy反向代理网关,能够将腾讯CodeBuddy包装为统一的/v1/chat/completions接口。在此,使用Docker Compose将它部署在NAS上。

项目地址

https://github.com/linguo2625469/workbuddy2api-panel

安装部署

本次使用Docker Compose的方式在绿联NAS的UGOS Pro中进行安装部署。

准备

首先下载项目文件,将其上传至NAS,并使用SSH登录进入NAS。

绿联NAS的UGOS Pro是基于Debian魔改的,共享文件夹依据存储池顺序以/volume{N}/{共享文件夹名}/...的形式被挂载。

进入NAS中的项目目录后,复制一份配置文件,并配置api_key

1
cp config.example.json config.json

安装

执行以下命令进行构建

1
sudo docker compose up -d --build

问题排查

这次在UGOS Pro上部署遇到了之前在Docker Desktop上没遇到的新坑,特此记录一下。

Ports are not available

docker compose启动时显示

1
Error response from daemon: ports are not available: exposing port TCP 0.0.0.0:7863 -> 127.0.0.1:0: listen tcp 0.0.0.0:7863: bind: An attempt was made to access a socket in a way forbidden by its access permissions.

此问题是由于项目默认的7863 端口,正好落在Windows系统保留的端口区间7786–7885之内。解决方法是修改docker-compose.yml中的端口号。

1
2
ports:
- "17863:7863" # 宿主机 17863 映射到容器内的 7863

RUN go mod download

docker构建时提示

1
2
3
4
=> ERROR [wb2api build 4/6] RUN go mod download                          60.4s
------
> [wb2api build 4/6] RUN go mod download:
60.36 go: github.com/cespare/xxhash/v2@v2.3.0: Get "https://proxy.golang.org/github.com/cespare/xxhash/v2/@v/v2.3.0.mod": dial tcp 142.251.34.209:443: i/o timeout

这个问题出现在Go模块代理上。proxy.golang.org是Google的服务器,国内直连必然超时解决办法为给构建阶段换国内Go模块代理。

编辑Dockerfile进行如下修改。

1
2
3
4
5
6
7
8
# syntax=docker/dockerfile:1
FROM golang:1.23-alpine AS build
WORKDIR /src
COPY go.mod ./
ENV GOPROXY=https://goproxy.cn,direct # ← 加这一行
RUN go mod download
COPY . .
...

RUN apk add –no-cache wget ca-certifi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 => ERROR [wb2api stage-1  2/11] RUN apk add --no-cache wget ca-certifi  703.7s
=> CACHED [wb2api build 2/6] WORKDIR /src 0.0s
=> CACHED [wb2api build 3/6] COPY go.mod ./ 0.0s
=> [wb2api build 4/6] RUN go mod download 1.6s
=> [wb2api build 5/6] COPY . . 0.1s
=> [wb2api build 6/6] RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s 21.4s
------
> [wb2api stage-1 2/11] RUN apk add --no-cache wget ca-certificates tzdata python3 bash && adduser -D -u 10001 app && mkdir -p /app/auths /app/data && chown -R app:app /app:
0.297 fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/main/x86_64/APKINDEX.tar.gz
421.0 WARNING: fetching https://dl-cdn.alpinelinux.org/alpine/v3.20/main: network connection aborted
421.0 fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/community/x86_64/APKINDEX.tar.gz
703.6 ERROR: unable to select packages:
703.6 tzdata (no such package):
703.6 required by: world[tzdata]

这个问题是运行阶段apk add连不上Alpine默认源dl-cdn.alpinelinux.org,还是通过添加代理来解决。

编辑Dockerfile,在apk add前加一行sed把默认源替换成阿里云镜像。

1
2
3
4
5
6
7
8
...
FROM alpine:3.20
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add --no-cache wget ca-certificates tzdata python3 bash \
&& adduser -D -u 10001 app \
&& mkdir -p /app/auths /app/data \
&& chown -R app:app /app
...

Read config permission denied

DOCKER运行时显示

1
load config: read config: open /app/config.json: permission denied

这个问题是镜像里容器默认以app用户(uid 10001)运行,而宿主机上config.json的属主是你自己,权限不允许uid 10001读它,所以启动读配置时被拒。

可以参考README-常见问题进行修改。

1
2
3
4
5
6
7
8
9
# 方案 1(推荐,非 root):让容器以你自己的 uid 运行——挂载目录本来就是你建的
PUID=$(id -u) PGID=$(id -g) docker compose up -d --force-recreate
# 或写进 .env 文件长期生效(.env 已被 .gitignore 忽略):
# echo "PUID=1000" > .env && echo "PGID=1000" >> .env

# 方案 2:把挂载目录属主交给容器默认用户(需要 sudo)
sudo chown -R 10001:10001 ./auths ./data ./config.json

# 方案 3:compose 设 user: "0:0" 以 root 运行(NAS/群晖不便 chown 时用)

使用反代后的API

由于workbuddy2api-panel只暴露OpenAI兼容接口,没有/v1/messages(Anthropic Messages)和 /v1/responses(OpenAI Responses)这两个协议端点,所以Codex和Claude Code可以使用CC Switch进行API中转。

Codex

Codex只能使用Responses API协议,具体步骤如下。

  • 切到Codex标签 → + → 自定义配置(Custom)。

  • 在API Key中填写workbuddy的api_key

  • 请求地址填写实际地址,如http://127.0.0.1:17863

  • 展开高级选项:

  • 上游格式:选 OpenAI Chat Completions(需开启路由)

  • 模型映射:获取并设置模型映射

Claude Code

Claude Code只能使用Anthropic Messages协议,具体步骤如下。

  • 切到 Claude Code 标签 → + → 自定义配置(Custom)。
  • 在API Key中填写workbuddy的api_key
  • 请求地址填写实际地址,如http://127.0.0.1:17863
  • 展开高级选项:
  • 上游格式:选 OpenAI Chat Completions(需开启路由)
  • 认证字段:保持默认 ANTHROPIC_AUTH_TOKEN;别改成 ANTHROPIC_API_KEY,否则会导致401/403
  • 模型映射:至少填「默认兜底模型」;可选把Sonnet/Opus 映射到主力模型、Haiku 映射到一个便宜快速的模型

Deepseek Harness

由于Deepseek Harness支持OpenAI Chat Cpmpletions,可以直接接入无需借助CC Switch反代。

  • API协议选择OpenAI Chat Cpmpletions
  • API地址后面需加/v1,比如http://127.0.0.1:17863/v1
--- 本文结束  The End ---