No description
  • Go 56.1%
  • TypeScript 41%
  • CSS 2%
  • JavaScript 0.4%
  • Dockerfile 0.2%
  • Other 0.2%
Find a file
2026-10-10 18:03:38 +08:00
cmd/server init 2026-10-10 11:50:17 +08:00
internal Direct link 2026-10-10 18:03:38 +08:00
web Direct link 2026-10-10 18:03:38 +08:00
.dockerignore init 2026-10-10 11:50:17 +08:00
.env.example init 2026-10-10 11:50:17 +08:00
.gitignore init 2026-10-10 11:50:17 +08:00
docker-compose.yml init 2026-10-10 11:50:17 +08:00
Dockerfile init 2026-10-10 11:50:17 +08:00
go.mod Direct link 2026-10-10 18:03:38 +08:00
go.sum Image thumbnail 2026-10-10 15:11:15 +08:00
Makefile init 2026-10-10 11:50:17 +08:00
plan.md init 2026-10-10 11:50:17 +08:00
README.md Direct link 2026-10-10 18:03:38 +08:00

drift

一个自建网盘。每个人只看到自己的虚拟文件夹,文件实际落在哪一块存储上由服务器决定。

功能

  • 多用户。第一个注册的账号是管理员,管理员可以把其他人设为管理员。
  • 文件夹和文件的上传、新建、重命名、移动、下载、删除。
  • 多个存储源。目前支持服务器本地目录和 S3(含兼容服务)。上传时按优先级选择还有空间的源。
  • 分享文件或文件夹。同一项可以有多条链接,可以带密码,也可以随时取消。
  • 文件直链。只能给单个文件创建,地址是 /d/ 加一段 UUID。打开即可下载,不需要登录。同一文件可以有多条直链,可以随时取消;删除文件后直链失效。
  • 图片在文件列表里显示缩略图。缩略图不超过 512×512,格式是 WebP,缓存在服务器本地。缓存可以随时删除,下次打开时会重新生成。

启动

# 改掉默认密钥后再暴露到网络上
export DRIFT_JWT_SECRET="$(openssl rand -hex 32)"
docker compose up -d --build

浏览器打开 http://localhost:8080,注册第一个账号。

在「存储源」里添加一个本地目录,容器里可用的路径是 /data 下面,例如 /data/files。这个目录位于名为 drift-data 的数据卷中。

S3 需要 Bucket、Access Key 和 Secret Key。MinIO 一类服务还要填写 Endpoint,并勾选 path-style。密钥只保存在数据库里,接口返回时会打码。下载时浏览器会跳转到对象存储上的临时链接,所以这个地址必须能从浏览器直接访问。

本地开发

docker compose up -d db
go run ./cmd/server
npm --prefix web install
npm --prefix web run dev

API 在 http://127.0.0.1:8080,界面开发服务器在 http://127.0.0.1:5173,并把 /api 代理到后端。

go test ./...

集成测试会连接 postgres://drift:drift@127.0.0.1:5432/postgres,没有数据库时自动跳过。

环境变量

变量 默认 说明
DATABASE_URL postgres://drift:drift@127.0.0.1:5432/drift?sslmode=disable Postgres 连接串
DRIFT_ADDR :8080 监听地址
DRIFT_JWT_SECRET 开发用固定值 登录态签名密钥,生产环境必须更换
DRIFT_WEB_DIR web/dist 前端构建目录
DRIFT_MAX_UPLOAD_BYTES 8589934592 单个文件上限,默认 8 GiB
DRIFT_COOKIE_SECURE false 只在 HTTPS 下发送登录 Cookie 时设为 true
DRIFT_THUMB_DIR 系统临时目录下的 drift-thumbs 缩略图缓存目录,可以随时清空

扩展存储驱动

存储后端实现 storage.Driver,并在 init 里 Register。用户的目录树只存在数据库中,驱动只处理服务器生成的对象键。

func init() { storage.Register(MyDriver{}) }

管理接口按驱动的 Type() 接收 JSON 配置,不需要改选择逻辑。选择规则是:在启用的源里,按优先级从高到低,挑第一个配额还放得下的。配额为 0 表示不限制。