轻量级、开箱即用的自托管文件中转平台。支持大文件上传、远程 URL / 磁力 / BT 下载,内置密码保护的管理后台、国际化与深浅主题切换。
- 公开下载列表 — 首页展示所有中转文件,无需登录即可搜索、下载
- 文件上传 — 拖拽或点击上传,实时进度显示,单文件最大支持 8GB(可配置)
- 远程下载 — HTTP/HTTPS URL 直接拉取中转,SSE 实时显示下载进度
- 磁力/BT — 支持
magnet:链接和.torrentURL(WebTorrent) - 文件管理 — 列表、搜索、排序、重命名、删除,全部受密码保护
- 分享链接 — 每个文件生成唯一链接,任何人可直接下载,无需登录
- 安全与防护 — 上传、接口调用均受防暴击拦截。底层全线路接入 AbortSignal 以解决取消失效引发的幽灵下载,并配备数据流截断机制彻底防止突破系统最大容量上线。
- 国际化 — 中文(简体)/ English 一键切换
- 主题 — 深色 / 浅色模式
| 路径 | 访问权限 | 说明 |
|---|---|---|
/ |
🌐 公开 | 文件下载列表(搜索、排序、下载) |
/admin |
🔐 需要登录 | 管理后台:上传文件 / 远程下载 / 文件管理 |
/share/:id |
🌐 公开 | 单文件分享页(显示文件信息 + 下载按钮) |
推荐方式:使用脚本部署,进程由 pm2 管理,自动重启 + 开机自启。
# 1. 将代码上传或克隆到 VPS
git clone https://github.com/sonnedu/file-du.git
cd file-du
# 2. 执行一键部署(自动安装 Node.js 20、依赖、配置环境、启动服务)
chmod +x deploy.sh && bash deploy.sh脚本会自动完成:
- ✅ 检测并安装 Node.js 20(若未安装,支持 Ubuntu / Debian / CentOS)
- ✅ 安装项目依赖(含 WebTorrent 编译)
- ✅ 交互式设置管理密码和端口
- ✅ 用 pm2 在后台启动服务
- ✅ 配置开机自启(
pm2 startup)
部署完成后访问 http://your-vps-ip:3000
pm2 status # 查看服务状态
pm2 logs file-du # 实时查看日志
pm2 restart file-du # 重启服务
pm2 stop file-du # 停止服务
nano .env # 修改配置(改完后 pm2 restart file-du)git pull
npm install --omit=dev
pm2 restart file-du复制模板并修改:
cp .env.example .env
nano .env| 变量 | 描述 | 默认值 |
|---|---|---|
ADMIN_PASSWORD |
管理后台登录密码(必须修改) | changeme123 |
SESSION_SECRET |
Session 签名密钥,随机字符串(必须修改) | — |
PORT |
服务监听端口 | 3000 |
MAX_FILE_SIZE |
单文件最大大小,支持人类可读格式 | 8GB |
MAX_TOTAL_SIZE |
系统总容量上限 | 50GB |
API_TOKEN |
curl/脚本访问的 API 密钥(不填则禁用) | — |
DOWNLOAD_TIMEOUT_MS |
远程下载超时时间(毫秒) | 7200000(2小时) |
MAX_CONCURRENT_DOWNLOADS |
最大并发下载数 | 10 |
LOG_LEVEL |
日志级别:trace/debug/info/warn/error |
info |
NODE_ENV |
运行环境,生产环境设为 production |
— |
MAX_FILE_SIZE=8GB # 推荐写法
MAX_FILE_SIZE=500MB
MAX_FILE_SIZE=1.5GB # 支持小数
MAX_FILE_SIZE=1024KB
MAX_FILE_SIZE=2TB
MAX_FILE_SIZE=8589934592 # 纯字节数也兼容支持单位:B / KB / MB / GB / TB(不区分大小写)
如果你更习惯 Docker:
cp .env.example .env && nano .env
docker-compose up -d
# 查看日志
docker-compose logs -f
# 更新
git pull && docker-compose up -d --build
# 停止
docker-compose down使用 Nginx 反代时,必须设置 client_max_body_size,否则大文件上传会报 413:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
client_max_body_size 8g; # ← 与 MAX_FILE_SIZE 保持一致
}
}所有持久化数据存储在 ./data/:
| 路径 | 内容 |
|---|---|
./data/db.json |
文件元数据数据库 |
./data/uploads/ |
上传 / 远程下载的文件 |
./data/temp/ |
BT 下载临时目录 |
npm install
cp .env.example .env # 按需修改
node server/index.js # 访问 http://localhost:3000
# 开发模式(自动重启)
npm run dev
# 代码检查
npm run lint # 检查问题
npm run lint:fix # 自动修复
npm run format # 格式化代码- 磁力/BT 下载 需要 VPS 能访问 DHT 网络(绝大多数 VPS 均可)
- Session 在服务重启后失效,需重新登录管理后台
- 上传 / 远程下载 API 均需 Session 认证,防止未授权的 curl 访问
- 配置
API_TOKEN后,curl 可绕过 Session 直接使用 Token 认证 - 建议配合 Nginx + HTTPS(Let's Encrypt)使用,保障传输安全
在 .env 中添加:
# 生成随机 Token
API_TOKEN=$(openssl rand -hex 32)
echo "API_TOKEN=$API_TOKEN" >> .envcurl -X POST https://your-site.com/api/remote \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/file.zip"}'返回:
{ "jobId": "job_1712345678_1", "type": "http" }curl "https://your-site.com/api/remote/status/job_1712345678_1" \
-H "Authorization: Bearer YOUR_TOKEN"下载中:
{
"jobId": "job_1712345678_1",
"status": "downloading",
"progress": 42.5,
"speed": 1048576,
"eta": 30,
"total": 104857600,
"downloaded": 44040192
}下载完成:
{
"jobId": "job_1712345678_1",
"status": "done",
"progress": 100,
"shareUrl": "https://your-site.com/share/AbCd123456",
"fileId": "AbCd123456",
"fileName": "file.zip",
"fileSize": 104857600
}#!/bin/bash
SITE="https://your-site.com"
TOKEN="YOUR_TOKEN"
URL="$1" # 用法: ./fetch.sh https://example.com/file.zip
# 提交任务
JOB_ID=$(curl -s -X POST "$SITE/api/remote" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"url\": \"$URL\"}" | jq -r '.jobId')
echo "📥 Job started: $JOB_ID"
# 轮询直到完成
while true; do
RESP=$(curl -s "$SITE/api/remote/status/$JOB_ID" \
-H "Authorization: Bearer $TOKEN")
STATUS=$(echo "$RESP" | jq -r '.status')
PROGRESS=$(echo "$RESP" | jq -r '.progress')
if [ "$STATUS" = "done" ]; then
echo "✅ 下载完成!"
echo "🔗 $(echo "$RESP" | jq -r '.shareUrl')"
break
elif [ "$STATUS" = "error" ]; then
echo "❌ 下载失败:$(echo "$RESP" | jq -r '.error')"
break
else
echo "⏳ 进度:${PROGRESS}%"
sleep 3
fi
done