Files
vue-driven-cloud-storage/DOCKER部署指南.md
WanWanYun 0f133962dc Initial commit - 玩玩云文件管理系统 v1.0.0
- 完整的前后端代码
- 支持本地存储和SFTP存储
- 文件分享功能
- 上传工具源代码
- 完整的部署文档
- Nginx配置模板

技术栈:
- 后端: Node.js + Express + SQLite
- 前端: Vue.js 3 + Axios
- 存储: 本地存储 / SFTP远程存储
2025-11-10 21:50:16 +08:00

1212 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 玩玩云 - Docker部署指南
> **📌 重要提示:代码自动适配域名**
>
> 本项目代码**完全支持域名动态适配**,无需修改任何代码:
> - ✅ 前端会自动使用当前访问的域名和协议http/https
> - ✅ 后端会从HTTP请求头动态获取域名信息
> - ✅ 上传工具配置文件会自动生成正确的API地址
>
> **您只需要:**
> 1. 配置宝塔/Nginx的反向代理指向Docker容器
> 2. 配置SSL证书可选推荐
> 3. 启动Docker容器
>
> **无需修改代码中的任何域名或IP地址**
## 目录
1. [系统要求](#系统要求)
2. [部署架构](#部署架构)
3. [快速部署步骤](#快速部署步骤)
4. [详细配置说明](#详细配置说明)
5. [常见问题解决](#常见问题解决)
6. [维护操作](#维护操作)
---
## 系统要求
### 服务器配置
- **操作系统**: Ubuntu 20.04+ / CentOS 7+ / Debian 10+
- **内存**: 最低 1GB RAM推荐 2GB+
- **磁盘**: 最低 10GB 可用空间
- **端口**: 需要开放以下端口
- `80` - HTTP (可选用于重定向到HTTPS)
- `443` - HTTPS (SSL访问)
- `8080` - 内部HTTP端口Docker容器
- `40001` - 后端API端口Docker容器
### 软件依赖
- **Docker**: 20.10.0+
- **Docker Compose**: 2.0.0+
- **Git**: 用于代码管理(可选)
- **Nginx**: 宝塔面板或系统级Nginx用于SSL终止和反向代理
---
## 部署架构
```
互联网
宝塔 Nginx (443 HTTPS) ← SSL证书在此层
Docker Nginx (8080 HTTP) ← 前端静态文件
Backend API (40001) ← Node.js + SQLite
SFTP服务器 (用户自建)
```
### 容器架构
```
docker-compose.yml
├── frontend (nginx:alpine)
│ ├── 静态文件: /usr/share/nginx/html
│ ├── Nginx配置: /etc/nginx/conf.d/default.conf
│ └── 端口: 8080:80, 8443:443
├── backend (wanwanyun-backend)
│ ├── Node.js应用: /app
│ ├── 数据库: /app/users.db (SQLite)
│ ├── 上传工具: /upload-tool
│ └── 端口: 40001:40001
└── certbot (certbot/certbot)
└── SSL证书: /etc/letsencrypt (可选)
```
---
## 快速部署步骤
### 步骤1: 准备服务器环境
```bash
# 1. 安装Docker
curl -fsSL https://get.docker.com | sh
systemctl start docker
systemctl enable docker
# 2. 安装Docker Compose
curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# 3. 验证安装
docker --version
docker-compose --version
```
### 步骤2: 上传项目文件
```bash
# 在服务器上创建项目目录
mkdir -p /var/www/wanwanyun
cd /var/www/wanwanyun
# 从本地上传所有文件(在本地执行)
scp -r C:/Users/Administrator/Desktop/ftp-web-manager/* root@YOUR_SERVER_IP:/var/www/wanwanyun/
```
或使用Git:
```bash
cd /var/www/wanwanyun
git clone YOUR_REPOSITORY_URL .
```
### 步骤3: 构建后端镜像
```bash
cd /var/www/wanwanyun
docker build -t wanwanyun-backend -f backend/Dockerfile .
```
**Dockerfile内容**(应该在 `backend/Dockerfile`:
```dockerfile
FROM node:18-alpine
WORKDIR /app
# 复制package.json和package-lock.json
COPY backend/package*.json ./
# 安装依赖
RUN npm install --production
# 复制应用代码
COPY backend/ ./
# 暴露端口
EXPOSE 40001
# 启动应用
CMD ["node", "server.js"]
```
### 步骤4: 启动容器
```bash
cd /var/www/wanwanyun
docker-compose up -d
# 查看容器状态
docker-compose ps
# 查看日志
docker-compose logs -f
```
### 步骤5: 配置宝塔Nginx或系统Nginx
#### 宝塔面板配置
1. **添加网站**
- 域名: `example.com`(替换为您的实际域名)
- 根目录: `/var/www/wanwanyun/frontend`(仅作为占位,实际不使用)
- PHP版本: 纯静态
2. **配置SSL证书**
- 在宝塔面板申请Let's Encrypt证书
- 或上传自有证书
3. **修改Nginx配置**
编辑网站配置文件(通常在 `/www/server/panel/vhost/nginx/您的域名.conf`:
```nginx
# HTTP重定向到HTTPS
server {
listen 80;
server_name example.com; # 替换为您的域名
return 301 https://$server_name$request_uri;
}
# HTTPS配置
server {
listen 443 ssl http2;
server_name example.com; # 替换为您的域名
# SSL证书路径宝塔自动配置
ssl_certificate /www/server/panel/vhost/cert/example.com/fullchain.pem;
ssl_certificate_key /www/server/panel/vhost/cert/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 反向代理到Docker容器
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# API反向代理
location /api/ {
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;
}
# 分享链接
location /s/ {
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;
}
# 访问日志
access_log /www/wwwlogs/example.com.log;
error_log /www/wwwlogs/example.com.error.log;
}
```
4. **重载Nginx**
```bash
nginx -t # 测试配置
nginx -s reload # 重载配置
```
#### 系统Nginx配置无宝塔
配置文件位置: `/etc/nginx/sites-available/wanwanyun.conf`
```nginx
# 与上述配置相同但SSL证书路径可能不同
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
```
创建软链接并重载:
```bash
ln -s /etc/nginx/sites-available/wanwanyun.conf /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
```
### 步骤6: 验证部署
1. **访问网站**
```
https://example.com # 替换为您的域名
```
2. **默认管理员账号**
- 首次启动会自动创建:
- 用户名: `admin`
- 密码: `admin123`
- ⚠️ **登录后请立即修改密码!**
3. **测试功能**
- ✓ 登录/注册
- ✓ SFTP配置
- ✓ 文件列表
- ✓ 文件上传/下载
- ✓ 文件分享
- ✓ 下载上传工具
---
## 详细配置说明
### 1. docker-compose.yml 配置
```yaml
version: '3.8'
services:
backend:
image: wanwanyun-backend
container_name: wanwanyun-backend
restart: always
ports:
- "40001:40001"
volumes:
- ./backend:/app
- /app/node_modules
- ./upload-tool:/upload-tool # 上传工具目录
environment:
- NODE_ENV=production
networks:
- wanwanyun-network
frontend:
image: nginx:alpine
container_name: wanwanyun-frontend
restart: always
ports:
- "8080:80" # HTTP端口
- "8443:443" # HTTPS端口可选如果使用Docker内SSL
volumes:
- ./frontend:/usr/share/nginx/html
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
- ./certbot/conf:/etc/letsencrypt # 可选
- ./certbot/www:/var/www/certbot # 可选
depends_on:
- backend
networks:
- wanwanyun-network
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
certbot: # 可选Docker内自动续期SSL证书
image: certbot/certbot
container_name: wanwanyun-certbot
restart: unless-stopped
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
networks:
wanwanyun-network:
driver: bridge
```
### 2. Nginx配置Docker内部
文件位置: `nginx/nginx.conf`
```nginx
server {
listen 80;
server_name localhost;
# 前端静态文件
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ =404;
}
# 后端API反向代理
location /api/ {
proxy_pass http://backend:40001;
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_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
# 分享链接重定向
location /s/ {
proxy_pass http://backend:40001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
```
### 3. 环境变量配置(可选)
创建 `.env` 文件:
```env
# 数据库配置
DB_PATH=/app/users.db
# JWT密钥请修改为随机字符串
JWT_SECRET=your-secret-key-change-this-in-production
# 后端端口
PORT=40001
# 最大上传大小(字节)
MAX_UPLOAD_SIZE=104857600
# 生产环境标志
NODE_ENV=production
```
### 4. 目录结构说明
```
/var/www/wanwanyun/
├── backend/ # 后端代码
│ ├── server.js # 主服务器文件
│ ├── package.json # Node.js依赖
│ ├── Dockerfile # 后端镜像构建文件
│ └── users.db # SQLite数据库自动生成
├── frontend/ # 前端代码
│ ├── index.html # 登录页面
│ ├── app.html # 主应用页面
│ ├── app.js # Vue.js应用逻辑
│ └── libs/ # 第三方库
│ ├── vue.global.js
│ ├── axios.min.js
│ └── fontawesome/
├── nginx/ # Nginx配置
│ ├── nginx.conf # 当前使用的配置
│ └── nginx.conf.example # 配置示例
├── upload-tool/ # 上传工具
│ └── dist/
│ └── 玩玩云上传工具.exe
├── certbot/ # SSL证书可选
│ ├── conf/
│ └── www/
└── docker-compose.yml # Docker编排文件
```
---
## 常见问题解决
### 问题1: 502 Bad Gateway
**症状**: 访问网站显示nginx 502错误
**原因**:
- Docker容器未启动
- 宝塔nginx配置错误HTTPS代理到HTTP容器
- 端口冲突
**解决方案**:
```bash
# 1. 检查容器状态
docker-compose ps
# 2. 查看容器日志
docker-compose logs backend
docker-compose logs frontend
# 3. 重启容器
docker-compose restart
# 4. 检查宝塔nginx配置
# 确保proxy_pass使用HTTP而不是HTTPS
proxy_pass http://127.0.0.1:8080; # 正确
# proxy_pass https://127.0.0.1:8443; # 错误如果Docker内未配置SSL
# 5. 检查端口占用
netstat -tulnp | grep 8080
netstat -tulnp | grep 40001
```
### 问题2: 上传工具无法下载
**症状**: 点击"下载上传工具"后浏览器报错
**原因**: Docker容器未挂载 `upload-tool` 目录
**解决方案**:
```bash
# 1. 检查docker-compose.yml中是否有以下配置
# backend服务的volumes部分应包含:
- ./upload-tool:/upload-tool
# 2. 检查文件是否存在
ls -la /var/www/wanwanyun/upload-tool/dist/
# 3. 重新创建容器(不是重启)
cd /var/www/wanwanyun
docker-compose up -d --force-recreate backend
# 4. 验证容器内可访问文件
docker exec wanwanyun-backend ls -la /upload-tool/dist/
```
### 问题3: SFTP连接失败
**症状**: 保存SFTP配置时报错 "Connection refused" 或 "Permission denied"
**原因**:
- SFTP服务器IP/端口错误
- 防火墙阻止
- 认证信息错误
- 服务器IP被SFTP服务器限制
**解决方案**:
```bash
# 1. 在服务器上测试SFTP连接
sshpass -p 'YOUR_PASSWORD' sftp -P 22 username@sftp.server.com
# 2. 检查防火墙
# 确保后端容器可以访问外部SFTP服务器
docker exec wanwanyun-backend ping sftp.server.com
# 3. 如果SFTP服务器限制IP
# 需要在SFTP服务器上添加Docker服务器IP到白名单
# 4. 检查后端日志
docker logs wanwanyun-backend | grep -i sftp
```
### 问题4: 文件删除失败 "Permission denied"
**症状**: 删除某些文件时提示权限被拒绝
**原因**: SFTP chroot安全限制根目录文件不可删除
**解决方案**:
这**不是bug**,是安全设计:
- `/` 根目录: 只读,系统配置文件(.bashrc等
- `/files` 目录: 可读写,用户工作目录
**建议**: 所有文件应上传到 `/files` 目录
### 问题5: 语法错误 "Uncaught SyntaxError"
**症状**: 浏览器控制台显示 app.js 语法错误
**原因**: JavaScript字符串中有字面换行符
**解决方案**:
```bash
# 检查是否有换行符错误
cd /var/www/wanwanyun/frontend
cat -A app.js | grep -n "\\$"
# 如果发现问题,重新从本地同步
scp C:/Users/Administrator/Desktop/ftp-web-manager/frontend/app.js root@SERVER:/var/www/wanwanyun/frontend/
# 重启前端容器
docker-compose restart frontend
```
### 问题6: 数据库锁定 "Database is locked"
**症状**: 多个用户同时操作时报数据库锁定错误
**原因**: SQLite不支持高并发写入
**解决方案**:
1. **短期方案**: 增加超时时间
修改 `backend/server.js`:
```javascript
const db = new Database('users.db', {
timeout: 10000 // 增加到10秒
});
```
2. **长期方案**: 迁移到PostgreSQL或MySQL
### 问题7: 端口冲突
**症状**: 启动容器时报错 "port is already allocated"
**解决方案**:
```bash
# 1. 查找占用端口的进程
netstat -tulnp | grep 8080
netstat -tulnp | grep 40001
# 2. 停止冲突的服务
systemctl stop nginx # 如果是系统nginx占用8080
# 3. 或修改docker-compose.yml中的端口映射
# 将 "8080:80" 改为 "8081:80"
# 相应修改宝塔nginx配置中的proxy_pass端口
```
### 问题8: SSL证书过期
**症状**: 浏览器显示证书无效警告
**解决方案**:
#### 使用宝塔面板:
```bash
# 在宝塔面板网站设置中点击"续签证书"
# 或使用宝塔计划任务自动续签
```
#### 使用Certbot (Docker):
```bash
# 手动续签
docker-compose run --rm certbot renew
# 重载nginx
docker-compose exec frontend nginx -s reload
# certbot容器会自动每12小时检查并续签
```
### 问题9: 容器内存不足
**症状**: 容器频繁重启,日志显示 "Out of memory"
**解决方案**:
```bash
# 1. 检查内存使用
docker stats
# 2. 限制容器内存在docker-compose.yml中
services:
backend:
# ... 其他配置
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M
# 3. 清理Docker缓存
docker system prune -a
```
### 问题10: X-Forwarded-Proto检测失败
**症状**: 下载上传工具时生成的URL是HTTP而不是HTTPS
**原因**: 反向代理未传递协议头
**解决方案**:
确保宝塔nginx配置包含:
```nginx
proxy_set_header X-Forwarded-Proto $scheme;
```
验证后端正确读取:
```javascript
// backend/server.js
const protocol = req.get('x-forwarded-proto') || req.protocol;
```
---
## 维护操作
### 日常维护
#### 查看日志
```bash
# 查看所有容器日志
docker-compose logs -f
# 查看特定容器日志
docker-compose logs -f backend
docker-compose logs -f frontend
# 查看最近100行
docker-compose logs --tail=100 backend
# 实时滚动日志
docker-compose logs -f --tail=50
```
#### 重启服务
```bash
# 重启所有容器
docker-compose restart
# 重启特定容器
docker-compose restart backend
docker-compose restart frontend
# 重新创建容器(配置更改后)
docker-compose up -d --force-recreate
```
#### 停止和启动
```bash
# 停止所有容器
docker-compose stop
# 启动所有容器
docker-compose start
# 完全停止并移除容器
docker-compose down
# 启动(创建容器)
docker-compose up -d
```
### 更新部署
#### 更新代码
```bash
# 1. 备份数据库
cp /var/www/wanwanyun/backend/users.db /var/www/wanwanyun/backend/users.db.backup
# 2. 拉取最新代码如果使用Git
cd /var/www/wanwanyun
git pull
# 3. 或从本地上传更新的文件
scp C:/Users/Administrator/Desktop/ftp-web-manager/backend/server.js root@SERVER:/var/www/wanwanyun/backend/
scp C:/Users/Administrator/Desktop/ftp-web-manager/frontend/app.js root@SERVER:/var/www/wanwanyun/frontend/
# 4. 重启容器
docker-compose restart backend frontend
```
#### 更新Docker镜像
```bash
# 1. 停止容器
docker-compose down
# 2. 重新构建后端镜像
docker build -t wanwanyun-backend -f backend/Dockerfile .
# 3. 拉取最新官方镜像
docker-compose pull frontend certbot
# 4. 启动
docker-compose up -d
```
### 备份和恢复
#### 备份数据
```bash
# 创建备份目录
mkdir -p /backup/wanwanyun/$(date +%Y%m%d)
# 备份数据库
cp /var/www/wanwanyun/backend/users.db /backup/wanwanyun/$(date +%Y%m%d)/
# 备份整个项目
tar -czf /backup/wanwanyun/$(date +%Y%m%d)/wanwanyun-full.tar.gz /var/www/wanwanyun
# 定期备份脚本添加到crontab
# 每天凌晨2点备份
# 0 2 * * * /usr/bin/tar -czf /backup/wanwanyun/$(date +\%Y\%m\%d)/backup.tar.gz /var/www/wanwanyun/backend/users.db
```
#### 恢复数据
```bash
# 停止容器
docker-compose down
# 恢复数据库
cp /backup/wanwanyun/20251108/users.db /var/www/wanwanyun/backend/
# 启动容器
docker-compose up -d
```
### 监控和性能
#### 监控容器资源
```bash
# 实时监控
docker stats
# 查看容器详细信息
docker inspect wanwanyun-backend
docker inspect wanwanyun-frontend
```
#### 性能优化
1. **启用Gzip压缩** (nginx/nginx.conf):
```nginx
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_min_length 1000;
```
2. **配置浏览器缓存**:
```nginx
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 7d;
add_header Cache-Control "public, immutable";
}
```
3. **限制并发连接**:
```nginx
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 10;
```
### 清理和优化
```bash
# 清理未使用的Docker资源
docker system prune -a
# 清理日志(如果过大)
truncate -s 0 /var/lib/docker/containers/*/*-json.log
# 查看磁盘使用
docker system df
```
---
## 安全建议
### 1. 修改默认配置
- 修改JWT_SECRET为随机字符串
- 修改数据库默认路径
- 限制管理员账号数量
### 2. 防火墙配置
```bash
# 只开放必要端口
ufw allow 80/tcp
ufw allow 443/tcp
ufw deny 40001/tcp # 不对外开放后端端口
ufw deny 8080/tcp # 不对外开放Docker HTTP端口
ufw enable
```
### 3. 日志审计
```bash
# 定期检查访问日志
tail -f /www/wwwlogs/example.com.log
# 查找异常请求
grep "POST /api/login" /www/wwwlogs/example.com.log | grep -v "200"
```
### 4. 定期更新
```bash
# 更新系统
apt update && apt upgrade -y
# 更新Docker镜像
docker-compose pull
docker-compose up -d
```
---
## 故障排查流程
### 基本诊断命令
```bash
# 1. 检查容器状态
docker-compose ps
# 2. 检查端口监听
netstat -tulnp | grep -E "80|443|8080|40001"
# 3. 测试后端API
curl http://localhost:40001/api/user/profile
# 4. 测试前端访问
curl http://localhost:8080
# 5. 检查nginx配置
nginx -t
# 6. 查看完整日志
docker-compose logs --tail=100
# 7. 进入容器调试
docker exec -it wanwanyun-backend sh
docker exec -it wanwanyun-frontend sh
```
### 故障决策树
```
网站无法访问
├── 502 错误
│ ├── 容器未启动 → docker-compose up -d
│ ├── nginx配置错误 → 检查proxy_pass
│ └── 端口冲突 → netstat检查
├── 404 错误
│ ├── 路由配置错误 → 检查nginx.conf
│ └── 文件不存在 → 检查/usr/share/nginx/html
├── 500 错误
│ ├── 后端崩溃 → docker logs backend
│ ├── 数据库错误 → 检查users.db权限
│ └── 代码错误 → 查看error.log
└── 连接超时
├── 防火墙阻止 → ufw status
├── 容器网络问题 → docker network ls
└── DNS解析失败 → ping域名
```
---
## 联系和支持
如果遇到无法解决的问题:
1. 收集以下信息:
- 错误信息截图
- `docker-compose logs` 输出
- `nginx -T` 配置输出
- 系统信息 `uname -a`
2. 检查日志中的错误堆栈
3. 参考本指南的"常见问题解决"部分
---
## 附录
### A. 完整的docker-compose.yml示例
参见项目根目录的 `docker-compose.yml` 文件
### B. 完整的Nginx配置示例
参见 `nginx/nginx.conf` 和 `nginx/nginx.conf.example`
### C. 后端Dockerfile示例
```dockerfile
FROM node:18-alpine
WORKDIR /app
COPY backend/package*.json ./
RUN npm install --production
COPY backend/ ./
EXPOSE 40001
CMD ["node", "server.js"]
```
### D. 环境检查脚本
```bash
#!/bin/bash
# 保存为 check-env.sh
echo "=== 玩玩云环境检查 ==="
echo -e "\n1. Docker版本:"
docker --version
echo -e "\n2. Docker Compose版本:"
docker-compose --version
echo -e "\n3. 容器状态:"
docker-compose ps
echo -e "\n4. 端口监听:"
netstat -tulnp | grep -E "80|443|8080|40001"
echo -e "\n5. 磁盘空间:"
df -h /var/www/wanwanyun
echo -e "\n6. 内存使用:"
docker stats --no-stream
echo -e "\n7. 最近错误日志:"
docker-compose logs --tail=20 | grep -i error
echo -e "\n=== 检查完成 ==="
```
---
**文档版本**: v1.0
**最后更新**: 2025-11-08
**适用版本**: 玩玩云 v1.0
---
## SFTP服务器配置指南
### 方案使用bindfs实现根目录可写的chroot
本项目推荐使用bindfs技术配置SFTP服务器可以实现
- ✅ **根目录可写** - 上传工具可直接上传到 `/filename`
- ✅ **Chroot隔离** - 用户只能访问独立空间,安全性高
- ✅ **无需修改代码** - 上传工具保持原样
### 配置步骤
#### 1. 安装必要工具
```bash
# 在SFTP服务器上执行
apt-get update
apt-get install -y bindfs openssh-server
```
#### 2. 创建用户和目录
```bash
# 创建真实数据目录
mkdir -p /var/sftp_data/wwy_upload
chown -R wwy_upload:wwy_upload /var/sftp_data/wwy_upload
chmod 755 /var/sftp_data/wwy_upload
# 创建chroot目录
mkdir -p /home/wwy_ftp_upload
# 创建用户
useradd -d /var/sftp_data/wwy_upload -s /bin/bash wwy_upload
printf 'wwy_upload:Wwy@2024Pass' | chpasswd
```
#### 3. 配置bindfs挂载
```bash
# 使用bindfs挂载关键步骤
bindfs --mirror=wwy_upload \
--force-user=root --force-group=root \
--perms=0755 \
/var/sftp_data/wwy_upload /home/wwy_ftp_upload
```
**参数说明**:
- `--mirror=wwy_upload`: 以wwy_upload用户身份镜像所有操作
- `--force-user=root --force-group=root`: 让目录看起来归root所有满足chroot要求
- `--perms=0755`: 设置目录权限
#### 4. 配置开机自动挂载
编辑 `/etc/fstab`,添加:
```
/var/sftp_data/wwy_upload /home/wwy_ftp_upload fuse.bindfs mirror=wwy_upload,force-user=root,force-group=root,perms=0755 0 0
```
#### 5. 配置SSH chroot
编辑 `/etc/ssh/sshd_config`,添加:
```
Match User wwy_upload
ChrootDirectory /home/wwy_ftp_upload
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
```
重启SSH服务
```bash
systemctl restart sshd
```
#### 6. 测试配置
```bash
# 测试上传到根目录
echo 'Test file' > /tmp/test.txt
sshpass -p 'Wwy@2024Pass' sftp wwy_upload@localhost <<EOF
put /tmp/test.txt /testfile.txt
ls -l /
bye
EOF
# 查看实际文件位置
ls -lh /var/sftp_data/wwy_upload/
```
### 技术原理
**bindfs工作原理**:
1. 真实数据存储在 `/var/sftp_data/wwy_upload`(用户拥有写权限)
2. bindfs将其挂载到 `/home/wwy_ftp_upload`显示为root所有
3. OpenSSH chroot到 `/home/wwy_ftp_upload`(满足安全要求)
4. 用户写入被镜像到真实目录实际文件归wwy_upload所有
**优势**:
- 绕过了OpenSSH chroot根目录必须只读的限制
- 保持了chroot的安全隔离特性
- 上传工具无需修改,直接上传到 `/filename`
---
## 下载功能说明
### 双模式下载
系统支持两种下载模式,自动选择:
#### 模式1: HTTP直接下载推荐速度快
**配置**: 在"设置"中填写"HTTP下载基础URL"
**工作方式**:
- 前端直接打开HTTP下载链接
- 浏览器从HTTP服务器直接下载
- 速度快,服务器压力小
**适用场景**:
- SFTP服务器同时提供HTTP访问
- 有独立的文件CDN服务
#### 模式2: SFTP流式下载默认无需配置
**配置**: 无需配置HTTP URL
**工作方式**:
1. 前端请求后端API `/api/files/download`
2. 后端通过SFTP连接文件服务器
3. 先获取文件大小(`sftp.stat()`
4. 设置响应头 `Content-Length`
5. 创建文件流(`sftp.createReadStream()`
6. 流式传输到浏览器(`stream.pipe(res)`
**特点**:
- ✅ 服务器零存储(不保存临时文件)
- ✅ 内存占用低(流式传输)
- ✅ 显示完整下载进度(文件大小、速度、剩余时间)
- ✅ 无需配置(开箱即用)
**代码实现** (`backend/server.js`):
```javascript
app.get('/api/files/download', authMiddleware, async (req, res) => {
const filePath = req.query.path;
const sftp = await connectToSFTP(req.user);
// 获取文件大小(用于显示下载进度)
const fileStats = await sftp.stat(filePath);
const fileSize = fileStats.size;
// 设置响应头
res.setHeader('Content-Type', 'application/octet-stream');
res.setHeader('Content-Length', fileSize); // 浏览器可显示进度
res.setHeader('Content-Disposition', 'attachment; filename="..."');
// 流式传输(服务器不保存临时文件)
const stream = sftp.createReadStream(filePath);
stream.pipe(res);
});
```
### 自动选择逻辑
前端自动判断使用哪种模式:
```javascript
downloadFile(file) {
if (file.httpDownloadUrl) {
// 如果配置了HTTP URL使用HTTP直接下载
window.open(file.httpDownloadUrl, "_blank");
} else {
// 如果没有配置通过后端SFTP下载
const link = document.createElement('a');
link.href = `${this.apiBase}/api/files/download?path=${filePath}&token=${token}`;
link.click();
}
}
```
---
## 版本更新日志
### v1.1 (2025-11-09)
**新增功能**:
- ✅ SFTP流式下载无需配置HTTP URL
- ✅ 下载进度显示(文件大小、速度、剩余时间)
- ✅ bindfs SFTP服务器配置方案
**改进**:
- ✅ 服务器零存储下载(纯中转)
- ✅ 下载逻辑自动选择HTTP/SFTP
- ✅ 优化用户体验
**修复**:
- ✅ 修复下载无进度显示的问题
- ✅ 修复未配置HTTP URL时无法下载的问题
### v1.0 (2025-11-08)
**初始版本**:
- ✅ 文件管理基础功能
- ✅ 文件分享功能
- ✅ 多用户系统
- ✅ 上传工具
- ✅ Docker部署
---
**文档版本**: v1.1
**最后更新**: 2025-11-09
**适用版本**: 玩玩云 v1.1