我最近又开始折腾文件分享这件小事。
说它是小事,是因为需求其实很朴素:把一个目录临时共享出去,让手机、平板、另一台电脑能直接访问;或者给朋友、同事丢一批文件,顺手开个上传入口,把资料收回来。说它不小,是因为只要你认真找过一圈工具,就会发现这类需求特别容易落进两个极端。一个极端是太重,动不动就是数据库、用户系统、反向代理、对象存储、后台管理整套一起上;另一个极端是太轻,轻到只能下载静态文件,稍微多一点需求就卡住了。
也是在这种背景下,我重新注意到了 [[dufs]]。第一次知道它的时候,我只是把它当成一个“更好看一点的 python -m http.server”。后来认真把它的 README、参数和接口看了一遍,我才意识到我之前其实低估了它。它不是一个勉强能用的小脚本,而是一个完成度已经相当高的文件服务工具:静态文件托管、上传、删除、搜索、权限控制、[[WebDAV]]、HTTPS、断点续传、curl 操作,这些能力它都给到了,而且还是用一个单独的可执行文件来完成。
dufs 是什么
dufs 是一个用 [[Rust]] 编写的开源文件服务项目,作者是 sigoden。它做的事情很直接,就是把某个目录,甚至某个单独文件,快速暴露成一个可通过浏览器、命令行和 WebDAV 客户端访问的服务。官方 README 对它的描述也很直白:这是一个支持静态文件服务、上传、搜索、访问控制和 WebDAV 的 utility file server。
我会喜欢这种项目,核心原因其实很简单:它没有试图把自己变成一个什么都想做的“私有云平台”。它非常专注,就盯着文件访问这一件事,把最常见的动作都补齐。你可以把它当成一个临时分享工具,也可以把它当成一个长期挂着的小型文件站点。很多时候,真正好用的工具不是功能表拉得有多长,而是边界很清楚,该有的都有,不该有的都不硬塞。
从 GitHub 官方仓库当前页面来看,dufs 已经积累了接近一万颗 star,latest release 是 v0.45.0,发布时间是 2025 年 9 月 4 日。对这类命令行项目来说,这其实已经很能说明问题了。它不是一个作者写着玩、大家点完 star 就走的仓库,而是一个持续有人用、有人提 issue、有人跟进 release 的成熟工具。
为什么我会注意到它
如果只是“开个目录让浏览器能访问”,替代方案其实很多。最经典的当然还是 Python 自带的 http.server。我自己也经常用,因为足够快,脑子里几乎不用重新记命令。问题也同样明显:它更像一个只负责把文件吐出去的最小实现。一旦你开始想要上传、搜索、权限控制、目录打包下载,或者希望前端界面别那么原始,它就会很快露出边界。
而 dufs 正好落在我很喜欢的那个位置上。它依然足够轻。官方给出的安装方式包括 cargo install dufs、brew install dufs,也可以直接下载 release 二进制文件,或者用 [[Docker]] 跑起来。也就是说,它保持了“单文件工具”的那种轻盈感。但与此同时,它又不是那种轻到只剩一个目录列表的项目,而是真的把很多会影响体验的细节都做进去了。
举个很实际的场景。假设我只是想把一个目录分享给局域网里的手机、平板、笔记本访问。如果只是只读,那很多工具都能做。可如果我还希望对方能直接拖拽上传文件,或者我想给不同人分配只读和可写权限,或者我自己想直接用 curl 去批量上传和移动文件,这时候 dufs 的价值就会一下子变得很明显。它不是用更复杂的部署成本去换功能,而是用相当克制的方式,把这些能力都塞进了一个可执行文件里。
它最打动我的几个点
官方 README 列出来的 feature 很多,但如果让我站在实际使用者角度去挑,我最看重的其实是下面这几件事。
第一,是它的文件操作能力真的完整。dufs 不只是“浏览和下载”,它还支持上传文件和文件夹、删除、搜索、创建目录、目录压缩下载,甚至支持断点续传。这一点非常重要,因为很多轻量文件服务只解决了“看得见文件”的问题,却没有解决“处理文件”的问题。真到日常使用时,能不能上传、能不能搜、能不能打包下载整个目录,这些能力会直接决定你是不是愿意把它留下来。
第二,是它同时照顾了浏览器用户和命令行用户。你可以直接用浏览器打开一个目录,得到一个清爽的 Web 界面;也可以完全把它当 API 来用。官方 README 里给出的例子非常实在,比如用 curl -T 上传文件,用 DELETE 删除,用 MKCOL 创建目录,用 MOVE 请求移动文件。对我来说,这一点很加分,因为很多时候我真正需要的不是一个“后台系统”,而是一个既能手工点一点,也能在 shell 脚本里无缝调用的工具。
第三,是权限控制做得轻,但不糊弄。dufs 提供了 --auth 参数,可以给不同用户配置不同路径和读写权限。像 README 里的 admin:admin@/:rw 和 guest:guest@/ 这种写法,已经足够覆盖掉大量个人和小团队的简单场景。更关键的是,它没有把权限这件事做成一个必须先初始化数据库、再点网页后台才能配置的重量级模块,而是维持在命令行就能读懂、就能维护的复杂度上。这种设计对个人用户非常友好。
第四,是它支持 [[WebDAV]]。很多人第一次看到这个功能可能不会立刻兴奋,但只要你有多设备协作需求,就会知道这个能力有多实用。它意味着 dufs 不只是一个网页下载器,而是能很自然地接到支持 WebDAV 的文件管理器、同步工具或者移动端 App 里。很多时候,工具真正开始有生命力,就是从“只能自己点网页”变成“能接进现有工作流”开始的。
dufs 适合什么场景
我觉得 dufs 最适合的,并不是那种需要复杂团队协作、在线文档编辑、数据库索引和对象存储后端的大型场景。那类需求还是应该交给 [[Nextcloud]] 这一类更完整的平台。dufs 的强项,是它把“文件服务”这件事本身做得非常顺手,所以特别适合下面几类使用方式。
一个是临时共享目录。比如你在家里或者办公室里,想把某个资料目录快速开放给同一网络里的设备访问;或者你要把一些安装包、视频、日志文件临时发给别人下载。这种情况下,dufs 的体验会比很多传统方案直接得多。进入目录,执行命令,打开端口,事情就结束了。
一个是轻量自建下载站或者资料站。如果你有一台常开的 NAS、迷你主机或者 VPS,想长期挂一个简单的文件浏览入口,dufs 也很适合。官方参数里有 --render-index、--render-try-index 和 --render-spa,这意味着它已经不只是纯目录列表工具了,而是可以兼顾静态站点托管和文件浏览两种模式。换句话说,你完全可以拿它来服务一个带 index.html 的静态页面。
再一个是自动化脚本场景。很多时候我并不想打开网页手工上传,而是希望在脚本里直接把文件推上去、移动目录、做健康检查。官方 README 里连 __dufs__/health 这样的健康检查路径和断点续传方式都给出来了。对喜欢命令行工作流的人来说,这类工具会比一个只能点 UI 的项目更耐用。
安装和启动其实非常简单
官方给出的安装方式很全,常见环境几乎都照顾到了。如果你已经有 [[Homebrew]],最直接的安装方式就是:
brew install dufs
如果你是 [[Rust]] 用户,也可以直接:
cargo install dufs
如果你不想在宿主机上安装任何额外东西,那就直接上 Docker:
docker run -v `pwd`:/data -p 5000:5000 --rm sigoden/dufs /data -A
我挺喜欢这个项目的一点,就是它的 hello world 特别短。只要执行下面这条命令,就可以把当前目录以只读方式启动出来:
dufs
默认情况下它会监听 5000 端口,服务当前目录。如果你想直接放开上传、删除、搜索、创建等操作,可以用官方最常见的参数:
dufs -A
这里的 -A 就是 allow all。对本地临时使用来说确实很方便,但如果你准备暴露到更大的网络环境里,我会建议你一定结合权限控制、反向代理或者网络范围限制来用。因为“方便”这件事,往往也意味着默认比较宽松。
用 Docker 部署 dufs
如果只是临时体验,官方 README 里那条 docker run 已经够用了。但如果你准备把 dufs 长期挂在一台主机上,我会更倾向于把它整理成一份更容易维护的 Docker 配置。下面这个例子是我根据官方 docker run 方式整理出来的等价写法,方便长期自建时使用:
services:
dufs:
image: sigoden/dufs:latest
container_name: dufs
restart: unless-stopped
ports:
- "5000:5000"
volumes:
- ./data:/data
command: /data -a admin:change-this-password@/:rw -a guest:guest@/
这份配置做的事情很简单:把宿主机当前目录下的 data 映射到容器里的 /data,容器启动后直接服务这个目录;管理员账号可读写,访客账号只读。对我来说,这样的部署方式已经足够覆盖掉大量家庭 NAS、小型 VPS 或者局域网资料站的场景。
如果你只是准备在本机或者内网里使用,我会建议先从最保守的方式起步,不要一上来就对公网开放。比如你可以只监听本机端口,然后通过反向代理统一接出去,或者只在局域网里暴露。dufs 本身支持 --tls-cert 和 --tls-key,也就是说它可以直接跑 HTTPS,但在实际部署里,我通常还是更愿意把 TLS 交给 [[Nginx]]、[[Caddy]] 或 [[Traefik]] 这一层处理。这样证书更新、域名管理和日志也会更统一。
如果你有静态站点需求,Docker 部署时也可以直接在 command 里加上 --render-index 或 --render-spa。如果你只是想做一个更友好的下载页面,甚至可以用 --assets 覆盖内置前端资源。README 里明确提到,dufs 的当前 UI 就是普通的 HTML、JS 和 CSS,没有引入复杂框架,所以要自己改一版界面,其实门槛并不算高。
我觉得最值得记住的几个参数
dufs 的参数不算特别多,但有几个我觉得一旦记住,就能覆盖掉八成使用场景。
最基础的是路径、绑定地址和端口。比如:
dufs Downloads -b 127.0.0.1 -p 8080
这条命令的意思很清楚:把 Downloads 目录启动在本机 8080 端口,只允许本机访问。很多时候,如果你只是拿它配合本地反向代理,或者准备通过 SSH 隧道访问,这种绑定方式会比直接监听所有地址稳妥得多。
如果你要做一个有权限控制的共享目录,我会比较推荐从最小权限出发,比如:
dufs -a admin:strong-password@/:rw -a guest:guest@/
这样管理员可读写,访客只能读。官方文档还提到,dufs 支持 sha-512 哈希密码,这一点对长期运行的场景更合适。唯一要注意的是,README 也明确提醒了,哈希密码和 digest auth 的组合有兼容性限制。
如果你不想让一些路径出现在列表里,可以用 --hidden。像 .git、日志文件、锁文件这种东西,完全没必要暴露给外部访问者:
dufs --hidden .git,.DS_Store,tmp --hidden '*.log,*.lock'
如果你是前端或者自建站用户,--render-index、--render-try-index 和 --render-spa 这三个参数也很值得留意。它们会让 dufs 不再只是吐目录列表,而是更自然地服务静态页面或者单页应用。
使用时我会注意什么
虽然我挺喜欢 dufs,但它也不是那种可以不带脑子直接对公网裸奔的工具。准确地说,它非常适合“我知道自己在开放什么、给谁开放、开放到什么程度”的场景。如果你把 -A 带着直接扔到公网,再挂一个弱密码,最后出问题,那不是工具的问题,是使用方式的问题。
所以如果我要把 dufs 长期挂起来,我通常会注意几件事。第一,尽量不要直接把管理能力暴露给所有人,尤其不要为了省事一直开 -A。第二,如果服务要出公网,最好放在反向代理后面,同时配 TLS。第三,把隐藏文件、日志文件、临时目录提前排除掉,这样目录更干净,也少一些不必要的泄露风险。第四,如果是 Docker 部署,就把数据目录单独挂卷,不要把容器当成唯一存储位置。
还有一点我很看重:如果你真正需要的是“团队协作式网盘”,那就不要勉强让 dufs 去承担它不擅长的任务。dufs 的好,就在于它把自己的边界守得很清楚。你越按它擅长的方式用,它就越舒服。
最后
如果让我用一句话来概括 dufs,我会说它是那种非常现代的命令行项目:安装轻,启动快,默认就能解决大部分问题,同时又没有因为追求轻量而把功能砍得太狠。
我自己现在越来越喜欢这类工具。它们不会一上来就要求你投入很重的学习成本,也不会强迫你接受一整套生态和设计哲学。你只要有一个很具体的问题,比如“我想把这个目录简单地共享出去”,它就能非常直接地给你一个足够好的答案。而 dufs 恰恰就是这类工具里完成度很高的一个。
如果你最近也在找一个比 python -m http.server 更完整、又比大型私有云轻得多的文件服务方案,我会很建议你试一下 dufs。很可能你用过一次之后,就会像我一样,把它长期留在自己的工具箱里。