它是什么
Open WebUI v0.12.0,跑在我家 .223 上的一个 Docker 容器,提供 ChatGPT 式的网页界面:多会话、长对话、上传文件都有。它本身不含模型,模型来自我填进去的 API——现在接的是 DeepSeek 官方,两个模型 deepseek-flash 和 deepseek-v4-pro。
为什么自己做
第三方客户端是「我 → 它家服务器 → API」多一跳,长对话容易被限流卡住。自建之后是「我 → 家里 .223 → API」直连,流式渲染在本地,历史会话存在自己机器上,长对话不会因为别人的服务端限流而卡。这是这个项目最实际的价值。
现在的状态
公网入口 https://chat.xiejun-server.top/ ,走 Let's Encrypt 证书、自动续期,手机电脑都能开;局域网 http://192.168.50.223:3080/ 也一样用。用独立子域名而不是子目录,是因为它的前端资源全是绝对路径,官方不支持子目录部署。手机「添加到主屏幕」就是 PWA,接近原生 App 的体验。注册已关闭,只有我和家人两个账号,各用各的 Key,日常在跑。
功能
- Docker 部署 Open WebUI v0.12.0,数据落在 /opt/open-webui/data,容器 restart unless-stopped
- 独立子域名加 NPM 反代,带 WebSocket 与 proxy_buffering off,流式输出不卡
- 已接入 DeepSeek 官方 API,两个模型实测流式对话与解题正常
- 自定义 PWA 清单与 Service Worker,安卓/iPhone 加到主屏幕即成 App
- 全局连接加模型访问授权,管理员与家人各用各的 Key
- 对外提供 OpenAI 兼容接口,可接第三方手机客户端
技术栈
使用 / 部署教程
一、准备
一台 Linux 机器,装好 Docker;一个能解析到入口 IP 的子域名(我用的是 chat 子域)。
二、拉镜像
直连 ghcr.io 拉 6.37GB 极慢,用南大镜像:
docker pull ghcr.nju.edu.cn/open-webui/open-webui:main
docker tag ghcr.nju.edu.cn/open-webui/open-webui:main ghcr.io/open-webui/open-webui:main
三、启动容器
把环境变量写进 deploy.sh 里,关键几项:
HF_ENDPOINT=https://hf-mirror.com # 容器内访问不了 huggingface,必须换镜像源
WEBUI_URL=https://chat.example.com
WEBUI_ADMIN_EMAIL=you@example.com
WEBUI_ADMIN_PASSWORD=<自己设一个强密码>
ENABLE_API_KEYS=True
端口映射 3080:8080,数据卷挂到 /opt/open-webui/data,重启策略 unless-stopped。首次启动会自动创建管理员账号并关闭注册,不用手工点注册。
四、反代
在 NPM 建一个 proxy host,转发到 内网IP:3080,要点有三个:开启 WebSocket、proxy_buffering off(流式输出必需)、80 端口留给 ACME 挑战并跳 HTTPS。不要试图挂在 /ai/ 这类子目录下,会和主站的 /static/、/assets/ 打架。
五、接模型
登录后进「设置 → 管理员 → 连接」,填服务商地址(如 https://api.deepseek.com/v1)和 Key,保存后模型列表里就能选。注意 v0.12.0 的接口路径变了,写脚本要用 POST /openai/config/update。
六、验证
curl -s localhost:3080/api/version
docker logs --tail 50 open-webui
再用公网地址登录,发一句长问题看流式是否顺滑,就基本确认没问题了。
注意
- API Key 用 600 权限存在本机 meta 目录,不要写进文档、不要推到任何外部平台;对话记录会进本机 git 备份,注意仓库只留本地。
- 容器内访问 huggingface.co 会 Network is unreachable,不设 HF_ENDPOINT=https://hf-mirror.com 可能直接起不来。
- 升级前先 pull 再 tag 到 ghcr.io 原名,然后跑 deploy.sh;数据卷不动,历史对话不会丢。