【实用的开源工具】webdav:一个轻量的 WebDAV 文件服务器
「实用的开源工具」系列:我只收集值得用的开源项目,写清楚它能做什么、怎么部署、有哪些坑,并在文末标明出处。内容整理自官方文档,核对日期 2026-10-31,具体版本以官方为准。命令和配置都摘自官方 README、Dockerfile 和 Compose 文件,本文没有做实机测试,请先在测试环境里走一遍。
项目信息卡
| 项目 | 说明 |
|---|---|
| 名称 | webdav(仓库 hacdias/webdav) |
| 做什么 | 官方描述是“简单、独立的 WebDAV 服务器”:把一个目录通过 WebDAV 协议提供出去,支持多用户、按用户设置目录和读写权限 |
| 许可证 | MIT |
| 仓库 | github.com/hacdias/webdav |
| 最近版本 | v5.17.3(2026-10-30 发布,查询于 2026-10-31) |
| 维护状态 | 仍在维护:仓库未归档,最近一次推送 2026-10-31,最新版本一天前刚发布;SECURITY.md 写明 5.x 是受支持的版本,低于 5.x 不再支持 |
| 运行方式 | 单个程序(可用二进制、go install、Homebrew 或 Docker),默认端口 6065,用一个配置文件(YAML、JSON 或 TOML) |
| 镜像 | ghcr.io/hacdias/webdav 和 Docker Hub 的 hacdias/webdav |
| 注意 | 它只是 WebDAV 服务端。README 里没有提到网页上传、分享链接这类“网盘界面”,只有可选的目录列表页(listing)。名字相近的 File Browser(filebrowser/filebrowser)是另一个项目,本文不涉及 |
它能做什么
- WebDAV 服务:支持常见的 WebDAV 方法,如
PROPFIND、PUT、MKCOL、COPY、MOVE、LOCK等。可以用支持 WebDAV 的客户端去访问;具体哪些软件、怎么配,官方 README 没有写,需要看各客户端的说明。 - 多用户:在配置里列出用户,使用 Basic 认证。每个用户可以有自己的目录和权限。
- 细粒度权限:权限分 C(创建)、R(读)、U(更新)、D(删除),默认只有
R;还可以用rules针对路径或正则单独设置。 - 多目录:
directories可以把多个目录作为虚拟根目录下的条目展示。 - HTML 目录列表:开启
listing后,用浏览器访问一个目录会看到列表页,而不是 WebDAV 的 XML。 - CORS、HSTS、TLS:都可以通过配置开启。
- 部分更新:支持兼容 SabreDAV
PATCH扩展的部分文件更新,细节见官方 README。
适合的场景:想要一个小而简单、能被手机、电脑、各种同步工具当作远程存储来用的服务,不想装一个很重的全家桶。
不适合的场景:你想要带网页界面的上传、预览、分享链接。这个项目不是干这个的。
部署
先建目录:
mkdir -p /opt/webdav/data && cd /opt/webdav第 1 步:生成密码哈希
官方的配置示例里有明文密码,但同时提示可以用 bcrypt 加密的密码,并且程序自带 webdav bcrypt 命令来生成。用 Docker 的话可以这样(bcrypt 子命令接收一个密码参数,输出哈希):
docker run --rm hacdias/webdav:v5.17.3 bcrypt '你的密码'输出的哈希形如 $2y$10$...。写进配置时前面要加 {bcrypt},见下面的例子。注意密码会留在 shell 历史里,这是通用的注意点,用完可以清掉历史。
第 2 步:写配置文件
/opt/webdav/config.yml。键名取自官方 README 的完整示例,我只留下需要的几项:
address: 0.0.0.0
port: 6065
# 容器里要监听所有地址,对外的访问范围由 Docker 的端口绑定控制
directory: /data
# 默认权限:只读。想让用户能写,在用户处覆盖
permissions: R
# 在反向代理后面时设为 true,日志里记录的是 X-Forwarded-For 的最后一项
behindProxy: true
users:
- username: alice
password: "{bcrypt}$2y$10$把这里换成上一步生成的哈希"
permissions: CRUD说明:
- 没有
users就没有认证。 官方说明:配置里检测到用户才会启用 Basic 认证,否则不做任何认证。所以一定要写用户。 permissions默认R(只读),可以组合C、R、U、D,不区分大小写。directory是用户能访问的目录;如果用户自己配置了directory,则用用户的。上面这个路径是容器里的路径,对应下面映射的./data。- 配置文件支持 YAML、JSON、TOML。官方还说明:顶层键用 camelCase,嵌套在某个部分里的键用 snake_case。
第 3 步:Compose 文件
官方仓库里有 compose.yml,但里面的镜像是 webdav:test(本地测试用),不能直接照抄。下面的结构参考它和 README 里的 docker run 命令,保存为 /opt/webdav/compose.yaml:
services:
webdav:
image: hacdias/webdav:v5.17.3
container_name: webdav
restart: unless-stopped
command: ["-c", "/config.yml"]
ports:
- "127.0.0.1:6065:6065"
volumes:
- ./data:/data
- ./config.yml:/config.yml:ro对应官方 README 里的 docker run 写法是:
docker run \
-p 6065:6065 \
-v ./config.yml:/config.yml:ro \
-v ./data:/data \
ghcr.io/hacdias/webdav -c /config.yml几点说明:
- 镜像标签:README 的示例是
latest,并说明可以用具体标签固定版本,也可以用main跟随开发分支。我写v5.17.3,是因为在 Docker Hub 上能查到这个标签;用之前请自己再确认,并按需换成更新的版本。 - 官方
compose.yml里还有一行security_opt(label=type:container_runtime_t)。我没有放进示例里,因为我没找到官方对它的说明。 - 端口绑定到
127.0.0.1,交给反向代理对外。
启动:
docker compose up -d
docker compose logs -f webdav第一次使用
- 想在浏览器里看一眼,可以先在
config.yml里加上listing:
listing:
enabled: true重启容器后,用浏览器访问 http://127.0.0.1:6065/(远程服务器可以先用 SSH 端口转发),输入用户名和密码,应该就能看到目录列表。官方说明:开启后,对目录的 GET 请求会返回 HTML 列表,而不是 PROPFIND 的响应。
- 想验证 WebDAV 本身是否正常,可以用 curl 发一个 PROPFIND 请求。这是 WebDAV 协议的通用用法,不是官方文档里的示例:
curl -u alice -X PROPFIND -H "Depth: 1" http://127.0.0.1:6065/返回 XML 列出目录内容,就说明服务在工作。
- 然后在你喜欢的 WebDAV 客户端里填服务地址、用户名和密码。各客户端的操作官方没有讲,这里不展开。
反向代理(Nginx)
官方 README 有专门的反向代理说明,核心是:要转发正确的头,否则会出现 502;同时 COPY 和 MOVE 请求带的 Destination 头里有完整域名,需要改写成只剩路径。官方的 Nginx 示例,我换成了本文的端口和域名,并补上 443:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name dav.example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
# Nginx 默认只允许 1M 的请求体,上传大文件会失败,按需调大(通用做法,非官方提示)
client_max_body_size 1G;
location / {
proxy_pass http://127.0.0.1:6065;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
# 让 COPY 和 MOVE 能正常工作:把 Destination 改写成只含路径
set $dest $http_destination;
if ($http_destination ~ "^https?://[^/]+(?<path>/.*)$") {
set $dest $path;
}
proxy_set_header Destination $dest;
}
}官方 README 里还有 Caddy 的示例,思路相同。
挂在子路径下
如果不想用单独的域名,而是 example.com/webdav:官方要求不要在代理里去掉子路径,因为 PROPFIND 的响应里带完整路径,客户端会拒绝不在自己请求范围内的条目。做法是把路径原样转发,并在配置里设:
prefix: /webdavNginx 用 location /webdav { ... },并且 proxy_pass 后面不要带路径,否则前缀会被替换。请求路径和 Destination 头都要带前缀,缺了会得到 400 Bad Request。
更新与卸载
更新:改 compose.yaml 里的版本标签(先确认新标签存在),然后:
cd /opt/webdav
cp -a data data.bak-$(date +%F) # 通用做法:升级前先备份,里面是你的文件
docker compose pull
docker compose up -d先看一下 Releases 的更新说明。
卸载:
cd /opt/webdav
docker compose down这只会删除容器。data 目录就是你的文件本身,config.yml 是用户配置,确认不再需要时才手动删除:
rm -rf /opt/webdav/data # 不可恢复,确认后再执行踩坑清单
- 没写
users就是不设防。 官方说明:只有配置了用户才会启用 Basic 认证,否则没有认证。如果端口又对外开放,任何人都能按默认权限访问。 - 默认权限只有读。
permissions默认R。上传、新建、改名失败,先看用户的权限有没有C、U、D。还有两个细节:LOCK算写操作,对已存在路径需要U、对不存在路径需要C;COPY或MOVE覆盖已有文件需要U,覆盖整个目录则需要对该目录及其下所有路径有D。 - 别用明文密码。 官方示例里为了演示有明文,实际请用
{bcrypt}开头的哈希。官方发布说明里还提到:格式不对的 bcrypt 哈希会在启动时被拒绝,所以复制哈希时别漏字符。 - Basic 认证走 HTTP 就是明文。 这是通用知识:务必走 HTTPS,要么在反向代理上加证书,要么用官方支持的
tls、cert、key让程序自己提供 TLS。 - HSTS 头只在程序自己处理 TLS 时才有效。 官方注释写明:在代理后面,请在代理上设置这个头。
- 反向代理漏了头会 502,漏了
Destination改写会让复制和移动失败。 照上面的配置写。官方 README 里的示例端口是 8080,别忘了换成 6065。 - 子路径不能让代理去掉。 需要
prefix配合,请求路径和Destination都要带前缀,否则返回400 Bad Request。 rules的匹配顺序和细节容易搞错。 官方说明:规则从后往前匹配,第一个匹配到的生效,所以靠后的规则优先;rulesBehavior默认是overwrite,也就是用户自己有规则时,会覆盖全局规则,而不是追加;regex规则是按字面匹配的,^/secret/不会匹配/secret本身,要写^/secret(/|$)。- 大小写不敏感或特殊文件系统上,别指望
rules。 官方说明:程序启动时会探测所在目录的文件系统是否区分大小写;在 Windows 上,一些会被系统当成别的文件的名字(含\、:,以点或空格结尾,设备名如CON,8.3 短名等)会直接返回 400。Linux 上的 FAT32 盘和 Docker Desktop 里挂载的 Windows 目录也可能出现短名问题,官方建议在这些位置不要依赖rules,或者在卷上关闭 8.3 短名。 - 容器默认以 root 运行。 我读了官方 Dockerfile,其中没有
USER指令,基础镜像是scratch,所以进程应该是 root,在./data里创建的文件属主也是 root。这是我从 Dockerfile 推断的,官方没有明说;想改用普通用户可以尝试 Compose 的user:,但官方文档没写过这种用法,需要自己验证。 - CORS 带凭据不能用
*。 要用credentials: true时,allowed_hosts要写具体来源,因为浏览器不接受带凭据又允许任意来源。不涉及浏览器里的网页访问就不用开 CORS。 - 防暴力破解。 官方 README 提供了 Fail2Ban 的过滤器和 jail 示例,用 Docker 时要配合
--log-driver journald和--name webdav。如果服务暴露在公网,建议配置。 - Docker 发布的端口会绕过 ufw 之类的防火墙。 所以示例绑定到
127.0.0.1,由 Nginx 对外。这是 Docker 的通用行为,不是这个项目特有的。 - 它不是备份工具。 这是通用提醒:通过 WebDAV 误删文件和直接在服务器上删除一样不可恢复,重要数据请另做备份。
出处
有想法或问题?去留言板留言 →