seafile 12 docker版本 端口映射问题

遇到的问题:

seafile 12 docker版本 端口映射问题,端口映射好之后,内网使用内网IP无法访问,参照的是https://bbs.seafile.com/t/topic/21047这个帖子

当前服务器版本

社区版本 seafile 12 docker版本

配置文件修改的部分

seafile-server.yml 配置增加如下内容

labels:
#caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}
caddy.reverse_proxy: “{{upstreams 80}}”
caddy: http://11.22.33.44

caddy.yml 配置增加如下内容

volumes:

-${SEAFILE_CADDY_VOLUME:-/opt/seafile-caddy}/config:/config/caddy

seadoc.yml 配置增加如下内容

labels:
#caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}
caddy: http://11.22.33.44

.env 配置增加如下内容

SEAFILE_SERVER_HOSTNAME=11.22.33.44:56899
SEAFILE_SERVER_PROTOCOL=http
SEADOC_SERVER_URL=http://11.22.33.44:56899/sdoc-server

seahub_settings.py配置增加如下内容

FILE_SERVER_ROOT = ‘http://11.22.33.44/seafhttp’

目前外网访问上传下载文件正常,内网无法访问,内网做了NAT回流之后内网也无法访问,请问下各位,如何实现内外网同时访问,比如内网访问用内网IP,外网访问用外网ip。

一、核心

Seafile 12 是**"单一规范地址"架构**:一个实例只能绑定一个访问地址(域名或 IP)。它内部生成的所有绝对链接 —— 网页 SERVICE_URL、上传/下载 FILE_SERVER_ROOT、SeaDoc SEADOC_SERVER_URL、通知服务器、同步客户端连接地址 —— 全部由 .env 里的 SEAFILE_SERVER_PROTOCOL + SEAFILE_SERVER_HOSTNAME 自动推导

所以「内网用户访问用内网 IP、外网用户访问用外网 IP」两套地址在同一个实例上无法同时完全可用。

  • 实现方案:用一个域名,做内外网分离解析(split-horizon DNS)——同一域名,内网解析到内网 IP、外网解析到公网 IP。

二、当前配置里几处问题

  1. FILE_SERVER_ROOT 在 12 已废弃
    官方 upgrade_notes_for_12.0.x.md 明确写:

“SERVICE_URL and FILE_SERVER_ROOT are removed. SERVICE_URL will be calculated from SEAFILE_SERVER_PROTOCOL and SEAFILE_SERVER_HOSTNAME”

您的配置写的 FILE_SERVER_ROOT = 'http://11.22.33.44/seafhttp' 不但不生效,还漏了端口 :56899

  1. Caddy 的 caddy 标签是"站点地址",必须和 SEAFILE_SERVER_HOSTNAME 完全一致
    Caddy(caddy-docker-proxy)按 Host 头路由。官方默认标签是:

    caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}
    

    您的 .envSEAFILE_SERVER_HOSTNAME=11.22.33.44:56899带端口),却把 seafile-server.ymlseadoc.yml 里的标签硬编码成 caddy: http://11.22.33.44无端口)。两者对不上。

  2. SEADOC_SERVER_URL.env 里写了也不生效
    官方 seafile-server.yml 里是这么推导的,根本不读你 .env 里的 SEADOC_SERVER_URL

    - SEADOC_SERVER_URL=${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}/sdoc-server
    

结论:你参照的帖子把「内网 IP 无法访问」归因于端口映射,其实是把 Caddy 的 Host 路由和 Seafile 的单主机名机制绕复杂了。只要把标签还原成官方默认、只在 .env 里正确填 SEAFILE_SERVER_HOSTNAME,端口映射就能正常工作。


三、修改基础配置

1. .env

COMPOSE_FILE='seafile-server.yml,caddy.yml,seadoc.yml'

# 这里填域名(见下文)
SEAFILE_SERVER_HOSTNAME=seafile.example.com:56899
SEAFILE_SERVER_PROTOCOL=http

# 删除 SEADOC_SERVER_URL 这一行(写了也不生效,12 会自动推导)

2. seafile-server.yml —— 标签还原为默认(不要硬编码 IP)

    labels:
      caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}
      caddy.reverse_proxy: "{{upstreams 80}}"

3. seadoc.yml —— 同样还原默认

    labels:
      caddy: ${SEAFILE_SERVER_PROTOCOL:-http}://${SEAFILE_SERVER_HOSTNAME:?Variable is not set or empty}
      caddy.1_handle_path: "/socket.io/*"
      caddy.1_handle_path.0_rewrite: "* /socket.io{uri}"
      caddy.1_handle_path.1_reverse_proxy: "{{upstreams 80}}"
      caddy.2_handle_path: "/sdoc-server/*"
      caddy.2_handle_path.0_rewrite: "* {uri}"
      caddy.2_handle_path.1_reverse_proxy: "{{upstreams 80}}"

4. caddy.yml —— 端口映射与 hostname 端口一致

如果你用 56899,Caddy 内部会监听 56899,宿主机也要映射 56899:

    ports:
      - 56899:56899

5. seahub_settings.py

删除手写的 FILE_SERVER_ROOT 那一行(12 已废弃,自动推导,无需手动维护)。


四、内网访问解决方案:域名 + 内外网分离解析

  • 自备域名,例如 seafile.example.com(内网也可以用自建 DNS 域名,比如 seafile.local)。
  • 内网 DNS(路由器或内部 DNS 服务器,或每台内网机器 /etc/hosts)把 seafile.example.com 解析到内网 IP,如 192.168.1.100
  • 公网 DNSseafile.example.com 解析到公网 IP 11.22.33.44

.env

SEAFILE_SERVER_HOSTNAME=seafile.example.com:56899   # 不带端口时就用标准 80/443
SEAFILE_SERVER_PROTOCOL=http

标签、FILE_SERVER_ROOTSEADOC_SERVER_URL 全部保持官方默认(由上面自动推导)。之后内网、外网用户都访问同一个 URL http://seafile.example.com:56899,DNS 自动把它们分别送到内网 IP / 公网 IP。


改完后:

docker compose down
docker compose up -d

对于NAT回流方案:

用公网 IP + NAT 回流

如果你只有公网 IP、没有域名,用下面这套一致的配置,然后内网机器也访问公网 IP(不是内网 IP):

.env

shell

复制

SEAFILE_SERVER_HOSTNAME=11.22.33.44:56899
SEAFILE_SERVER_PROTOCOL=http

seafile-server.yml / seadoc.yml 标签用默认配置,caddy.yml 映射 56899:56899

关于你"做了 NAT 回流还不行":

  • 内网机器请直接测试公网地址(注意:是公网 IP,不是内网 IP):
curl -v http://11.22.33.44:56899/
  • 能返回 Seafile 页面 → 说明回流其实通了,之前"不通"很可能是因为你用内网 IP去访问(内网 IP 不在 Caddy 的站点地址里,必然 404)。
  • 超时/连接被拒 → 是路由器不支持 hairpin(NAT loopback),常见于家用路由器。这种情况只能换支持回流的设备,或改用方案。
  • 即使 Caddy 允许你用内网 IP 打开网页,Seafile 生成的下载链接、SeaDoc 地址仍指向 11.22.33.44:56899,内网用户点下载还是会绕回公网。所以纯 IP 场景下"内网用内网 IP"这条路走不通,只能"内外网统一用公网 IP"。

谢谢指点,我试试,有问题,继续向您请教