Skip to content

Commit 47fcf96

Browse files
committed
docs(lobehub): 更新自托管部署文档说明 S3 配置要点
详细解释了 S3_SET_ACL 参数的作用机制,以及如何正确配置 S3_ENDPOINT 和 S3_PUBLIC_DOMAIN 来解决容器内外网络访问问题。 当 S3_SET_ACL=0 时,LobeHub 会基于 S3_ENDPOINT 生成预签名预览地址, 如果使用 host.docker.internal 则浏览器无法访问该地址。 新增关于网络配置的详细说明,包括: - 使用 macmini 作为统一的主机访问地址 - 在 network-service 中添加 extra_hosts 映射 - 上传链路中浏览器直传目标的地址解析机制 提供了排查 hostname 解析问题的辅助脚本。
1 parent 8349fc3 commit 47fcf96

2 files changed

Lines changed: 58 additions & 1 deletion

File tree

ai/self-hosted/lobehub/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,3 +289,54 @@ docker compose up --force-recreate rustfs-init
289289
- `APP_URL`
290290

291291
把它们改成你本机浏览器可以直接访问的地址即可。
292+
293+
另外还要确认当前 compose 没把 `S3_SET_ACL` 关掉。
294+
295+
- 现在默认配置应当让 `S3_SET_ACL=1`
296+
- 原因是 LobeHub 在 `S3_SET_ACL=0` 时,会回退成基于 `S3_ENDPOINT` 生成预签名预览地址
297+
- 如果你的 `S3_ENDPOINT``http://host.docker.internal:9000`,那这个地址对容器可用,但对宿主机浏览器通常不可用
298+
- 典型现象就是上传成功后,前端马上拿到 `host.docker.internal` 开头的文件 URL,然后界面报错或显示 `Bad Gateway`
299+
300+
还要注意一个更关键的上传链路差异:
301+
302+
- 当前版本的附件上传会先调用 `upload.createS3PreSignedUrl`
303+
- 这个接口生成的浏览器直传目标,使用的也是 `S3_ENDPOINT`
304+
- 也就是说,`S3_ENDPOINT` 不只是“容器内访问 RustFS”的地址,它还会直接暴露给浏览器
305+
- 如果这里写成 `host.docker.internal`,浏览器通常会在上传前的 `OPTIONS/PUT` 阶段直接失败
306+
307+
当前仓库默认建议改成:
308+
309+
- `S3_ENDPOINT=http://macmini:9000`
310+
- `S3_PUBLIC_DOMAIN=http://macmini:9000`
311+
312+
如果 `macmini` 是这台机器在 Tailscale / MagicDNS 里的稳定地址,推荐统一这样配置。
313+
314+
同时要记得:
315+
316+
- 浏览器侧会直接访问 `S3_ENDPOINT`
317+
- 容器侧也必须能解析 `macmini`
318+
- 当前 compose 使用了 `network_mode: service:network-service`
319+
- 因此主机名映射要加在 `network-service` 上,而不是 `lobe`
320+
321+
当前默认做法就是:
322+
323+
- `.env``S3_ENDPOINT=http://macmini:9000`
324+
- `.env``S3_PUBLIC_DOMAIN=http://macmini:9000`
325+
- `docker-compose.yml` 里的 `network-service.extra_hosts` 增加 `macmini:host-gateway`
326+
327+
这样同一 Tailnet 里的其它客户端、宿主机浏览器和容器内服务都会统一使用 `macmini`,避免再出现上传直传地址和对外访问地址分裂的问题。
328+
329+
排查时可以直接在宿主机执行:
330+
331+
```bash
332+
python3 - <<'PY'
333+
import socket
334+
for host in ['host.docker.internal', 'localhost']:
335+
try:
336+
print(host, socket.gethostbyname(host))
337+
except Exception as exc:
338+
print(host, 'ERR', exc)
339+
PY
340+
```
341+
342+
如果 `host.docker.internal` 在宿主机侧解析失败,而浏览器里看到的文件地址又正好是这个域名,根因基本就确定了。

ai/self-hosted/lobehub/docker-compose.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ services:
66
restart: always
77
ports:
88
- '${LOBE_PORT}:3210' # LobeChat
9+
extra_hosts:
10+
# `lobehub` 复用 `network-service` 的网络命名空间,
11+
# 所以需要在这里补 `macmini -> host-gateway`,让容器内也能访问宿主机上的 RustFS。
12+
- 'macmini:host-gateway'
913
command: tail -f /dev/null
1014
networks:
1115
- lobe-network
@@ -57,7 +61,9 @@ services:
5761
- 'S3_ACCESS_KEY_ID=${RUSTFS_ACCESS_KEY}'
5862
- 'S3_SECRET_ACCESS_KEY=${RUSTFS_SECRET_KEY}'
5963
- 'LLM_VISION_IMAGE_USE_BASE64=1'
60-
- 'S3_SET_ACL=0'
64+
# 默认开启 ACL,让返回给浏览器的文件 URL 走 `S3_PUBLIC_DOMAIN`,
65+
# 避免在宿主机浏览器里收到 `host.docker.internal` 这类仅容器内可解析的地址。
66+
- 'S3_SET_ACL=${S3_SET_ACL:-1}'
6167
- 'SEARXNG_URL=http://searxng:8080'
6268
- 'REDIS_URL=${REDIS_URL}'
6369
- 'REDIS_PREFIX=lobechat'

0 commit comments

Comments
 (0)