拒绝云盘刺客!我用 OmNi 自建了一个私密文件分享站,真香!
其实折腾自托管这事儿,我也不是第一次干了,以前搞过 Nextcloud,那玩意儿好用是好用,但太重了,我就想给公司几个开发传个 Log 或者是给客户发个安装包,犯不着动用那种全家桶级别的工具。后来也试过一些简单的,比如那些基于 Go 写的单文件分发,又觉得功能太简陋,界面丑得我拿不出手。OmNi 给我的第一感觉就是:这作者审美在线,而且是真的懂我们这些整天跟机器打交道的人到底想要什么。
它的核心卖点就是“隐私”和“简单”。说白了,它就是为了让你在自己的服务器上起一个专属的文件中转站,没有乱七八糟的广告,没有速度限制(当然,除非你服务器带宽只有 1Mbps 那就当我没说),最重要的是,数据都在你手心里攥着。
这东西到底是个啥?
源码地址:https://codeberg.org/lagging/omni
刚看到 OmNi 这个名字的时候,我还没反应过来,心想这又是什么缩写。进去看了一下源码和介绍,发现作者的思路特别清晰。它不是那种想取代你硬盘的网盘,它更像是一个“文件传输枢纽”。你把文件丢上去,生成一个链接,发给别人,别人下完,你甚至可以设置让它自动消失。
为了把这玩意儿跑起来,我专门开了一台吃灰好久的轻量云服务器。环境其实挺简单的,现在这种项目,你要是不支持 Docker,那基本上就没法玩了。我这人有个毛病,能用容器解决的绝对不直接在系统上装环境,省得以后卸载的时候还得清理那一堆依赖库。
咱们开干:部署过程中的那些坑
部署 OmNi 其实没几步,但我中间还是稍微折腾了一下。先说最基础的吧,你得有个 Docker 环境。我这里用的 docker-compose,因为这玩意儿好管理,想改个端口或者挂载个目录,改下 YAML 文件就行了。

我当时写的配置文件大概长这样:
version: '3.8'
services:
omni:
image: omni-file-share:latest # 这里记得去拉取最新的镜像
container_name: omni-app
restart: always
ports:
- "8080:3000"
volumes:
- ./data:/app/data
- ./uploads:/app/uploads
environment:
- NODE_ENV=production
- DATABASE_URL=file:./data/omni.db
- JWT_SECRET=找个长点的随机字符串放这里
- NEXTAUTH_SECRET=也是随便填个复杂的
- NEXTAUTH_URL=http://你的域名或者IP:8080写到这儿我想起个事,就是那个 NEXTAUTH_URL。我刚开始部署的时候,随手填了一个,结果登录的时候老是跳回 404,后来才反应过来,这玩意儿对协议和端口特别敏感。如果你打算在外面套个 Nginx 做反代,记得这里的 URL 一定要写成带 https 的最终访问地址,不然那个 Cookie 校验能折磨死你。
还有就是文件权限的问题。很多人起容器的时候喜欢用 root,虽然省事儿,但万一这工具以后爆出个啥漏洞,你整个宿主机就裸奔了。我建议还是专门建个账号,把 uploads 目录的归属权弄好。我在测试的时候,发现如果挂载的宿主机目录权限没给够,上传大文件的时候进度条会一直卡在 99%,那感觉就像是你要冲过终点线了结果被人拽住了裤衩。
界面与体验:这就是我要的极简

把容器跑起来后,打开浏览器,那界面真的让我眼前一亮。没有那种土里土气的侧边栏,也没有密密麻麻的按钮。它就是很清爽的一个框,你可以把文件直接拽进去。
我试着传了一个 2GB 的数据库备份镜像,整个过程非常平滑。OmNi 处理上传逻辑的时候好像用了分片,反正我看着监控里的流量波动还挺稳的。传完之后,你可以设置这个文件的有效期。这功能我太喜欢了,有时候我给别人发个敏感文档,我只想让他看一小时,或者下载一次就失效,OmNi 都能做到。
说到隐私,这东西在代码层面好像做了一些加密处理。它不像某些工具,你把文件传上去,它在后台存的文件名跟你传的一模一样。OmNi 会对文件名进行哈希处理,存放在服务器上的就是一堆乱码,只有通过前端的那个特定 Key 才能还原出来。这就算以后服务器被人黑了,拿到了这一堆文件,他也分不清哪个是财务报表,哪个是小姐姐的照片。
进阶玩法:套上 Nginx 反代
虽然直接用端口访问也行,但作为搞运维的,不搞个域名、套个 SSL 证书,总觉得这事儿没做完。我用的是 Nginx,配置其实也挺常规,但有几个点得注意下,不然大文件上传会报 413 Request Entity Too Large。
server {
listen 443 ssl;
server_name share.yourdomain.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
# 重点在这里,不然传不了大文件
client_max_body_size 0;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Websocket 支持,如果 OmNi 以后有实时进度推送,这个得加上
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}那个 client_max_body_size 0; 记得一定要加,或者给个你觉得够用的值(比如 10240M)。我有次忘了配这个,传个 Windows 镜像传到一半被 Nginx 给拦腰斩断了,查了半天日志才发现是 Nginx 的默认限制太小了。
聊聊自托管的意义
可能有人会问,现在这么多现成的工具,为什么要费这劲自己折腾?说实话,刚开始我也觉得麻烦。但当你真的经历过:某盘因为所谓的违规(其实就是你加密了个压缩包)把你的技术文档删了;或者当你急着给客户发资料,结果对方因为没装那个网盘的客户端,死活下不下来的时候,你就会明白这种“自给自足”的快乐。
OmNi 这种工具,它把复杂留给了我们这些部署的人,把简单留给了最终的使用者。我发个链接给客户,他点开就能下,不需要注册,不需要登录,这种体验在现在这个到处是“围墙花园”的互联网里,简直就是一股清流。
而且,对于我们运维来说,这也是一种资源利用。那些空闲的 VPS,除了跑跑脚本,跑个这种实用的小工具,偶尔应急用一下,性价比极高。我甚至给它挂载了一个对象存储(S3),通过 Rclone 把本地目录映射到云端,这样我连服务器硬盘空间都不用担心了,想存多少存多少,这套组合拳打下来,真的挺爽。
常见的小问题和碎碎念
在使用过程中,我也遇到过一些莫名其妙的小毛病。比如有时候数据库锁死,可能是因为我那台小鸡的 IO 性能实在太差了。OmNi 默认用的是 SQLite,这玩意儿虽然轻量,但在高并发写入的时候还是有点吃力。不过好在咱们这只是个人用,或者小团队内部用,并发一般不会太高。
还有就是移动端的适配,OmNi 做得居然还不错。我用手机浏览器打开,传张照片什么的,操作逻辑很顺手。
我一直在想,为什么这类开源项目能层出不穷。可能大家真的对那种被巨头掌控的数据环境感到疲惫了吧。每一行代码、每一个配置参数,都是我们在为了那点可怜的数字主权在奋斗。虽然听起来有点宏大叙事了,但当你看着 docker ps 里那个 Up 状态的 OmNi 时,那种安全感确实是真实的。
总结一下,OmNi 不是那种全能型的选手,它更像是一个专注某一项技能的特种兵。它简单、快、注重隐私,能满足你对文件分享最原始的需求。如果你也跟我一样,受够了那些云盘的各种限制,手里又刚好有一两台服务器,我真心建议你花个十几分钟把它搭起来。
折腾的过程本身也是一种学习,哪怕只是改改配置文件,处理下 Nginx 的报错,这些细碎的经验积累起来,才是一个技术人成长的基石。别总是等别人喂饭,自己动手,丰衣足食。
如果你在部署过程中遇到什么奇奇怪怪的报错,比如容器起不来,或者界面白屏什么的,记得多看看日志。报错信息往往就在那几行字里,静下心来读一读,比去到处问人要管用得多。
好了,今天就唠到这儿吧。如果你觉得这玩意儿有点意思,或者你有更厉害的推荐,欢迎跟我交流。咱们搞技术的,不就是得互相启发、互相进步嘛。
觉得这篇文章对你有帮助的话,别忘了点个赞或者转发给那些同样在找文件分享工具的朋友。你的支持就是我继续折腾、继续分享的最大动力。咱们下次再聊别的黑科技!
关注我,不迷路!
在这里,我只聊最接地气的运维实战,分享最硬核的技术干货。从 Docker 到 K8s,从 Python 脚本到各种好玩的开源项目,咱们一起在机房的灯火中探索技术的边界。
公众号:运维躬行录
个人博客:躬行笔记
引导关注@运维躬行录,获取更多实战干货与工具推荐!