摘要:Nextcloud 太重,Seafile 部署麻烦?本文拆解自研开源私有云盘 zhyCloudDisk,实现跨用户秒传、分片断点续传、部门权限、Electron 双向同步、文件编辑锁,附带架构解析、核心难点、Docker 部署实操,适合全栈开发者学习参考。
作者 :凤城老人
开源地址(三平台同步)
- GitHub:https://github.com/pollybird/zhy-cloud-disk
- Gitee:https://gitee.com/pollybird/zhy-cloud-disk
- GitCode:https://gitcode.com/pollybird/ZhyCloudDisk
开源协议 :Apache 2.0|稳定版本:v1.2.0
一、痛点:为什么还要自己写私有云盘?
想搭一套私有网盘,大部分人第一反应就是 Nextcloud、Seafile。
实际踩坑之后才发现问题不少:
- 组件繁多,部署配置繁琐,2 核 4G 轻量服务器跑起来压力很大;
- Web 端与桌面客户端体验割裂,双向同步容易丢文件、冲突处理拉胯;
- 想要简单定制功能,插件体系封闭,二次开发门槛高;
- 小团队办公缺少轻量化部门权限,多人编辑文档互相覆盖。
既然现成方案不够顺手,那就自己造轮子。
zhyCloudDisk(钟毓私有云盘) ,定位轻量自建网盘,面向个人备份、小团队文档协作,同时也是一套可学习的全栈实战项目。
v1.2.0 已经落地:跨用户全局秒传、大文件断点续传、多级部门网盘、文件排他编辑锁、Electron 双向同步、插件扩展、Docker 单容器开箱即用。
本文不讲基础使用教程,重点拆解架构取舍、核心技术难点、底层实现思路,后端、全栈、Electron 开发者可以直接参考学习。
二、整体架构与技术选型
2.1 完整技术栈
后端 Python
- Web 框架:Flask 3.0,蓝图做业务模块化拆分
- ORM:SQLAlchemy,一套代码兼容 SQLite / MySQL / PostgreSQL
- 鉴权:Flask‑JWT‑Extended,Access/Refresh 双 Token 无感刷新
- 定时任务:APScheduler,替代重型消息队列
- 缓存:Redis(可选,低配环境自动降级内存缓存)
Web 前端 - Vue3 + Vite + Pinia + Element Plus
Electron 桌面客户端(核心亮点) - Electron33 + electron‑vite
- better‑sqlite3:本地维护同步快照数据库
- chokidar:本地文件系统监听
- system‑keyring:操作系统密钥环加密存储 Token,避免明文泄露
2.2 架构分层
采用前后端分离 + API‑Service‑ORM 三层架构
- API 层:只负责参数校验、请求响应,不写业务逻辑;
- Service 业务层:所有核心逻辑下沉,事务、权限、文件处理全部在这里实现;
- ORM 数据层:模型解耦,支持多数据库切换。
架构简易示意
text
浏览器 / Electron客户端
↓
Nginx(静态资源托管 + /api反向代理)
↓
Gunicorn + Flask多进程服务
↓
蓝图路由 → Service业务层 → 插件扩展框架
↓
SQLAlchemy ORM|本地磁盘文件|Redis缓存
2.3 几个关键的技术取舍
很多人会问,为什么不用 Celery?为什么单容器内置 MySQL?
- 放弃 Celery 消息队列
网盘后台任务都是低频次运维工作:过期分片清理、失效锁回收、存量文件指纹收敛。APScheduler 完全够用,少部署一套 Broker,降低服务器资源消耗。 - Redis 设计为可选项
Docker 环境自动开启 Redis;手动部署没有安装 Redis,系统自动切内存缓存,低配机器也能跑。 - Web 和桌面客户端复用同一套 API
上传、秒传、文件锁、权限全部后端统一处理,不会出现网页能用、客户端逻辑不一致的 bug。
三、核心技术难点拆解
3.1 跨用户全局秒传:逻辑文件与物理文件分离
大部分开源网盘秒传仅限同一个用户,不同用户上传相同文件依旧重复占用磁盘。
本项目把文件拆分为两套模型:
- file_blob 物理文件表:全局唯一,存储 MD5 指纹、文件大小、磁盘路径、引用计数;
- file_node 逻辑文件表 :用户视角的文件,保存文件名、目录、权限,关联 blob_id。
秒传流程: - 客户端本地预计算完整文件 MD5;
- 请求接口查询全局指纹库;
- 如果 MD5 已存在:直接新建逻辑记录,引用计数 + 1,零带宽完成上传;
- 不存在,则走分片上传;
- 用户删除文件只删除逻辑记录;引用计数减为 0 时,定时任务真正删除磁盘文件。
数据库事务 + 行级锁保证并发上传、并发删除场景下引用计数不会错乱。后台定时任务对老文件补算指纹,存量数据也可以享受磁盘复用。
3.2 分片上传 & 双向断点续传
触发阈值:文件大于 20MB 自动分片,单片 5MB,并发 3 片,单片失败自动重试 3 次,分片会话有效期 24 小时。
上传流程:
- 创建分片上传会话 ID;
- 并发上传分片,每一片单独 MD5 校验;
- 断网重连,服务端返回已经上传完成的分片,客户端仅补发缺失部分;
- 全部分片接收完毕,服务端合并文件,再次校验完整文件 MD5;
- APScheduler 每 10 分钟扫描,清理过期分片会话,防止磁盘被垃圾碎片占满。
下载端兼容标准HTTP‑Range 206断点续传,本地生成.zhy.part临时文件,中断之后继续下载,结束校验 MD5 保证文件完整。
3.3 多级部门网盘:带开关的企业权限模型
v1.1.0 新增部门网盘,和个人网盘完全隔离,配额、权限、数据互不干扰。
- 支持无限级部门树,每个部门独立存储配额;
- 文件夹粒度权限:
read_only / read_write / denied,权限可以设置到期时间; - 管理员分两种:仅管理本部门、管理本部门及全部子部门;
- 保护机制:部门下还有文件时,禁止直接删除部门,防止误删数据。
一个比较巧妙的设计:功能全局开关。
通过环境变量ZHY_DEPARTMENT_DRIVE=true/false控制是否开启部门网盘。关闭之后接口依旧注册,通过全局拦截器统一返回业务错误码,个人网盘不受任何影响,版本升级对旧数据完全兼容。
3.4 文件排他锁,解决多人编辑覆盖问题
团队协作最头疼的场景:两个人同时编辑一份文档,保存之后互相覆盖丢失内容。
v1.2.0 实现服务端中心化排他锁:
- Electron 客户端打开可写权限的部门文件,自动申请排他锁;
- 持有锁期间,其他用户无法覆盖上传、重命名、移动、删除该文件,仅能只读查看,页面显示是谁占用了锁;
- 文件保存回传云端成功,主动释放锁;
- 2 分钟心跳续约,如果客户端崩溃、断网,后台自动回收锁,避免死锁。
3.5 Electron 双向同步引擎实现
桌面同步是这个项目最大的差异化功能,也是复杂度最高的模块。
由四大组件协同工作:
- Watcher:chokidar 监听本地文件变更,做事件防抖,避免编辑器频繁保存产生大量无效事件;
- Poller:定时拉取云端变更日志,把云端改动同步到本地;
- Coordinator 事件协调器:重点解决痛点 ------chokidar 重命名会触发删除 + 新增事件,协调器识别这种配对,转为重命名 / 移动,不会粗暴删除重传;
- TaskQueue 任务队列 :任务串行、去重、失败重试,保证同步顺序。
配套能力: - Token 使用系统密钥环加密存储,配置文件不会明文保存账号信息;
- 两种冲突策略可选:保留双方副本 / 以最后修改时间为准;
- 托盘后台驻留,关闭窗口继续同步;完整同步日志,方便排查同步失败。
3.6 插件化扩展架构
不改动主业务代码就可以扩展功能:
后端插件支持注册路由、定时任务、文件预处理钩子;
前端PluginPreview动态组件,根据文件类型渲染预览;
原生支持图片、音视频、PDF 预览,插件可以扩展 Office 文档、3D 模型预览等能力。
四、部署:单容器一键跑起来
最大优势:All‑in‑One Docker 镜像,内置 Nginx + Gunicorn + MySQL + Redis,不需要额外部署数据库中间件,轻量服务器直接运行。
4.1 Docker Hub 镜像直接运行
bash
docker run -d \
--name zhy-cloud-disk \
-p 8080:80 \
-e ZHY_ADMIN_USERNAME=admin \
-e ZHY_ADMIN_PASSWORD=Admin12345 \
-v zhy-instance:/app/instance \
-v zhy-storage:/app/storage \
-v zhy-mysql:/var/lib/mysql \
pollybird/zhy-cloud-disk:latest
访问 http://服务器IP:8080,容器首次启动自动建库、初始化管理员账号。
4.2 源码部署脚本
bash
git clone https://gitee.com/pollybird/zhy-cloud-disk.git && cd zhy-cloud-disk
./deploy.sh init #生成.env配置
./deploy.sh up
脚本内置init / up / down / restart / logs / update / shell运维命令。
4.3 数据卷说明,升级不怕丢数据
zhy‑instance:系统配置zhy‑storage:全部用户上传文件zhy‑mysql:数据库业务数据
删除容器不会删除 Volume,重建、升级服务数据全部保留。
也支持无 Docker 手动部署,适合二次开发调试。
五、测试保障
项目有完整自动化测试用例,保证版本迭代稳定性:
- 后端:pytest 覆盖模型、Service 业务逻辑、API 接口、事务逻辑;
- Electron 客户端:vitest,127 个单元测试,覆盖同步引擎、队列、哈希计算、锁生命周期;
- 发布流程:每次版本发布,必须跑完全量测试 + 前端构建校验。
六、后续迭代计划
v1.2.0 已经完成基础核心能力,后续重点开发:
- 分享增强:提取码、访问密码、访问统计、精细化有效期;
- WebDAV 协议支持,资源管理器直接挂载云盘;
- 抽象存储层,支持 S3 兼容对象存储;
- 完善插件开发文档,丰富插件生态。
七、写在最后
zhyCloudDisk 不是堆砌功能的玩具项目,它兼顾实际使用价值和学习价值。
从文件指纹秒传、分片大文件上传,到团队权限模型、Electron 双向同步,每一个功能都来源于真实使用中的痛点。
开源不易,如果项目对你有帮助,欢迎 Star,遇到 Bug 欢迎提交 Issue,也欢迎 PR 一起参与迭代。