删除不需要的文件
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
# 应用配置
|
||||
ENVIRONMENT=development
|
||||
DEBUG=True
|
||||
|
||||
# 服务器配置
|
||||
HOST=0.0.0.0
|
||||
PORT=8000
|
||||
|
||||
# 数据库配置
|
||||
DATABASE_URL=mysql+pymysql://root:password@localhost:3306/mytest_db
|
||||
|
||||
# Redis配置
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
|
||||
# JWT配置
|
||||
SECRET_KEY=your-super-secret-key-change-this-in-production
|
||||
ALGORITHM=HS256
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||
REFRESH_TOKEN_EXPIRE_DAYS=7
|
||||
|
||||
# 文件上传配置
|
||||
UPLOAD_DIR=uploads
|
||||
MAX_FILE_SIZE=10485760 # 10MB
|
||||
|
||||
# CORS配置
|
||||
ALLOWED_HOSTS=["http://localhost:3000", "http://127.0.0.1:3000", "*"]
|
||||
|
||||
# 日志配置
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=logs/app.log
|
||||
@@ -1,30 +0,0 @@
|
||||
# 测试环境配置
|
||||
ENVIRONMENT=development
|
||||
DEBUG=True
|
||||
|
||||
# 服务器配置 - 测试端口
|
||||
HOST=0.0.0.0
|
||||
PORT=8010
|
||||
|
||||
# 数据库配置
|
||||
DATABASE_URL=mysql+pymysql://root:password@localhost:3306/mytest_db
|
||||
|
||||
# Redis配置
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
|
||||
# JWT配置
|
||||
SECRET_KEY=test-secret-key-for-testing-environment
|
||||
ALGORITHM=HS256
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||
REFRESH_TOKEN_EXPIRE_DAYS=7
|
||||
|
||||
# 文件上传配置
|
||||
UPLOAD_DIR=uploads
|
||||
MAX_FILE_SIZE=10485760 # 10MB
|
||||
|
||||
# CORS配置 - 允许所有来源
|
||||
ALLOWED_HOSTS=["*"]
|
||||
|
||||
# 日志配置
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=logs/app.log
|
||||
@@ -1,314 +0,0 @@
|
||||
# 云盘后端Linux打包指南
|
||||
|
||||
## 概述
|
||||
|
||||
本指南说明如何使用PyInstaller将云盘后端应用打包成Linux可执行文件,以便在没有Python环境的Linux服务器上部署运行。
|
||||
|
||||
## 文件说明
|
||||
|
||||
### 打包配置文件
|
||||
- `build.spec` - PyInstaller配置文件,定义了打包规则和依赖
|
||||
- `build_linux.py` - 完整的打包脚本,包含检查、清理、打包和部署包创建功能
|
||||
- `requirements-build.txt` - 打包所需的依赖包列表
|
||||
|
||||
### 部署配置文件
|
||||
- `cloud-drive.service` - systemd服务配置文件
|
||||
- `install.sh` - 自动化安装脚本
|
||||
- `uninstall.sh` - 卸载脚本
|
||||
- `quick_build.sh` - 快速打包脚本
|
||||
|
||||
## 环境要求
|
||||
|
||||
### 开发环境(打包用)
|
||||
- Python 3.8+
|
||||
- PyInstaller 5.0+
|
||||
- 操作系统:Linux或Windows(交叉编译)
|
||||
|
||||
### 目标环境(部署用)
|
||||
- Linux 64位系统
|
||||
- MySQL 5.7+ 或 8.0+
|
||||
- Redis (可选)
|
||||
- 至少512MB内存
|
||||
- 至少100MB磁盘空间
|
||||
|
||||
## 打包步骤
|
||||
|
||||
### 方法一:使用完整打包脚本
|
||||
|
||||
```bash
|
||||
# 1. 进入后端目录
|
||||
cd backend
|
||||
|
||||
# 2. 安装依赖
|
||||
pip install -r requirements.txt
|
||||
pip install pyinstaller
|
||||
|
||||
# 3. 运行打包脚本
|
||||
python build_linux.py
|
||||
|
||||
# 或者只清理构建目录
|
||||
python build_linux.py --clean
|
||||
```
|
||||
|
||||
### 方法二:使用快速脚本
|
||||
|
||||
```bash
|
||||
# 1. 进入后端目录
|
||||
cd backend
|
||||
|
||||
# 2. 运行快速打包脚本
|
||||
chmod +x quick_build.sh
|
||||
./quick_build.sh
|
||||
```
|
||||
|
||||
### 方法三:手动打包
|
||||
|
||||
```bash
|
||||
# 1. 安装PyInstaller
|
||||
pip install pyinstaller
|
||||
|
||||
# 2. 清理之前的构建
|
||||
rm -rf build dist __pycache__
|
||||
|
||||
# 3. 执行打包
|
||||
pyinstaller --clean build.spec
|
||||
|
||||
# 4. 创建部署包
|
||||
mkdir -p deploy/logs deploy/uploads
|
||||
cp dist/cloud-drive-server deploy/
|
||||
cp .env.example deploy/
|
||||
```
|
||||
|
||||
## 打包输出
|
||||
|
||||
成功打包后,会生成以下文件:
|
||||
|
||||
```
|
||||
backend/
|
||||
├── deploy/ # 部署包目录
|
||||
│ ├── cloud-drive-server # 主程序可执行文件
|
||||
│ ├── start.sh # 启动脚本
|
||||
│ ├── .env.example # 环境配置示例
|
||||
│ ├── README.md # 部署说明
|
||||
│ ├── logs/ # 日志目录
|
||||
│ └── uploads/ # 上传文件目录
|
||||
├── build/ # PyInstaller构建临时文件
|
||||
├── dist/ # 打包输出目录
|
||||
└── build.spec # 打包配置文件
|
||||
```
|
||||
|
||||
## 部署到Linux服务器
|
||||
|
||||
### 方法一:使用自动化安装脚本
|
||||
|
||||
```bash
|
||||
# 1. 将整个deploy目录上传到服务器
|
||||
scp -r deploy/ user@server:/tmp/cloud-drive
|
||||
|
||||
# 2. 在服务器上运行安装脚本(需要root权限)
|
||||
sudo /tmp/cloud-drive/install.sh
|
||||
```
|
||||
|
||||
### 方法二:手动部署
|
||||
|
||||
```bash
|
||||
# 1. 创建服务用户
|
||||
sudo useradd -r -s /bin/false cloud-drive
|
||||
|
||||
# 2. 创建安装目录
|
||||
sudo mkdir -p /opt/cloud-drive/{logs,uploads}
|
||||
|
||||
# 3. 复制文件
|
||||
sudo cp deploy/cloud-drive-server /opt/cloud-drive/
|
||||
sudo cp deploy/.env.example /opt/cloud-drive/
|
||||
sudo chmod +x /opt/cloud-drive/cloud-drive-server
|
||||
|
||||
# 4. 设置权限
|
||||
sudo chown -R cloud-drive:cloud-drive /opt/cloud-drive
|
||||
|
||||
# 5. 配置环境变量
|
||||
sudo cp /opt/cloud-drive/.env.example /opt/cloud-drive/.env
|
||||
sudo nano /opt/cloud-drive/.env # 编辑配置
|
||||
|
||||
# 6. 安装systemd服务
|
||||
sudo cp cloud-drive.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable cloud-drive
|
||||
|
||||
# 7. 启动服务
|
||||
sudo systemctl start cloud-drive
|
||||
```
|
||||
|
||||
## 环境配置
|
||||
|
||||
编辑 `/opt/cloud-drive/.env` 文件:
|
||||
|
||||
```env
|
||||
# 数据库配置
|
||||
DATABASE_URL=mysql+pymysql://用户名:密码@主机:端口/数据库名
|
||||
|
||||
# Redis配置
|
||||
REDIS_URL=redis://主机:端口
|
||||
|
||||
# JWT配置
|
||||
JWT_SECRET_KEY=你的密钥
|
||||
JWT_EXPIRE_MINUTES=30
|
||||
|
||||
# 运行环境
|
||||
ENVIRONMENT=production
|
||||
|
||||
# 文件上传配置
|
||||
UPLOAD_DIR=uploads
|
||||
MAX_FILE_SIZE=10485760 # 10MB
|
||||
```
|
||||
|
||||
## 服务管理
|
||||
|
||||
```bash
|
||||
# 查看服务状态
|
||||
sudo systemctl status cloud-drive
|
||||
|
||||
# 启动服务
|
||||
sudo systemctl start cloud-drive
|
||||
|
||||
# 停止服务
|
||||
sudo systemctl stop cloud-drive
|
||||
|
||||
# 重启服务
|
||||
sudo systemctl restart cloud-drive
|
||||
|
||||
# 查看日志
|
||||
sudo journalctl -u cloud-drive -f
|
||||
|
||||
# 查看应用日志
|
||||
tail -f /opt/cloud-drive/logs/app.log
|
||||
```
|
||||
|
||||
## 验证部署
|
||||
|
||||
```bash
|
||||
# 健康检查
|
||||
curl http://localhost:8000/api/v1/health
|
||||
|
||||
# API文档
|
||||
curl http://localhost:8000/docs
|
||||
|
||||
# 根路径
|
||||
curl http://localhost:8000/
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 1. 打包问题
|
||||
|
||||
**问题**: `ImportError: No module named 'xxx'`
|
||||
**解决**: 在 `build.spec` 的 `hiddenimports` 列表中添加缺失的模块
|
||||
|
||||
**问题**: 打包文件过大
|
||||
**解决**: 在 `build.spec` 的 `excludes` 列表中添加不需要的库
|
||||
|
||||
### 2. 运行问题
|
||||
|
||||
**问题**: 端口被占用
|
||||
```bash
|
||||
# 检查端口占用
|
||||
sudo netstat -tlnp | grep 8000
|
||||
# 或修改配置文件中的端口
|
||||
```
|
||||
|
||||
**问题**: 数据库连接失败
|
||||
```bash
|
||||
# 检查数据库配置
|
||||
cat /opt/cloud-drive/.env
|
||||
# 测试连接
|
||||
mysql -h 主机 -u 用户 -p 数据库名
|
||||
```
|
||||
|
||||
**问题**: 权限问题
|
||||
```bash
|
||||
# 检查文件权限
|
||||
ls -la /opt/cloud-drive/
|
||||
# 修复权限
|
||||
sudo chown -R cloud-drive:cloud-drive /opt/cloud-drive/
|
||||
```
|
||||
|
||||
### 3. 性能优化
|
||||
|
||||
**启用UPX压缩**(减小文件大小):
|
||||
```bash
|
||||
# 安装UPX
|
||||
sudo apt install upx # Ubuntu/Debian
|
||||
sudo yum install upx # CentOS/RHEL
|
||||
|
||||
# 在build.spec中确保 upx=True
|
||||
```
|
||||
|
||||
**启用strip**(减小文件大小):
|
||||
```bash
|
||||
# 在build.spec中确保 strip=True
|
||||
```
|
||||
|
||||
## 更新和维护
|
||||
|
||||
### 更新应用
|
||||
|
||||
```bash
|
||||
# 1. 停止服务
|
||||
sudo systemctl stop cloud-drive
|
||||
|
||||
# 2. 备份当前版本
|
||||
sudo cp /opt/cloud-drive/cloud-drive-server /opt/cloud-drive/cloud-drive-server.bak
|
||||
|
||||
# 3. 替换新版本
|
||||
sudo cp new-cloud-drive-server /opt/cloud-drive/cloud-drive-server
|
||||
sudo chmod +x /opt/cloud-drive/cloud-drive-server
|
||||
|
||||
# 4. 启动服务
|
||||
sudo systemctl start cloud-drive
|
||||
```
|
||||
|
||||
### 日志管理
|
||||
|
||||
日志会自动轮转(通过logrotate配置),也可以手动管理:
|
||||
|
||||
```bash
|
||||
# 查看日志轮转配置
|
||||
cat /etc/logrotate.d/cloud-drive
|
||||
|
||||
# 手动执行日志轮转
|
||||
sudo logrotate -f /etc/logrotate.d/cloud-drive
|
||||
```
|
||||
|
||||
### 监控
|
||||
|
||||
可以使用以下工具监控服务:
|
||||
|
||||
```bash
|
||||
# systemd监控
|
||||
sudo systemctl status cloud-drive
|
||||
|
||||
# 进程监控
|
||||
ps aux | grep cloud-drive-server
|
||||
|
||||
# 网络连接
|
||||
sudo netstat -tlnp | grep 8000
|
||||
|
||||
# 磁盘空间
|
||||
df -h /opt/cloud-drive
|
||||
```
|
||||
|
||||
## 安全建议
|
||||
|
||||
1. **防火墙配置**: 只开放必要的端口(8000)
|
||||
2. **用户权限**: 使用专用用户运行服务,避免root权限
|
||||
3. **文件权限**: 确保敏感文件只有服务用户可读
|
||||
4. **SSL/TLS**: 在生产环境使用HTTPS
|
||||
5. **定期更新**: 保持系统和依赖包的更新
|
||||
|
||||
## 技术支持
|
||||
|
||||
如遇到问题,请检查:
|
||||
1. 系统日志:`journalctl -u cloud-drive`
|
||||
2. 应用日志:`/opt/cloud-drive/logs/app.log`
|
||||
3. 配置文件:`/opt/cloud-drive/.env`
|
||||
4. 服务状态:`systemctl status cloud-drive`
|
||||
@@ -1,174 +0,0 @@
|
||||
# 云盘应用端口8080启动和测试指南
|
||||
|
||||
## 🚀 快速启动
|
||||
|
||||
### 方法1:自动启动并测试(推荐)
|
||||
```bash
|
||||
cd backend
|
||||
chmod +x start_and_test_8080.sh
|
||||
./start_and_test_8080.sh
|
||||
```
|
||||
|
||||
### 方法2:手动启动
|
||||
```bash
|
||||
cd backend
|
||||
|
||||
# 1. 启动服务器
|
||||
python3 start_8080.py
|
||||
|
||||
# 2. 在另一个终端测试API
|
||||
python3 test_api_8080.py
|
||||
```
|
||||
|
||||
### 方法3:自动模式
|
||||
```bash
|
||||
cd backend
|
||||
python3 start_8080.py --auto
|
||||
```
|
||||
|
||||
## 📋 测试的API端点
|
||||
|
||||
### 基础端点
|
||||
- `GET /` - 根路径
|
||||
- `GET /health` - 健康检查
|
||||
- `GET /api/v1/health` - API健康检查
|
||||
- `GET /docs` - Swagger API文档
|
||||
- `GET /redoc` - ReDoc文档
|
||||
- `GET /openapi.json` - OpenAPI规范
|
||||
|
||||
### 认证端点
|
||||
- `POST /api/v1/auth/register` - 用户注册
|
||||
- `POST /api/v1/auth/token` - 用户登录
|
||||
|
||||
### 文件端点
|
||||
- `GET /api/v1/files` - 文件列表
|
||||
- `POST /api/v1/files/upload` - 文件上传
|
||||
|
||||
## 🔧 环境要求
|
||||
|
||||
- Python 3.8+
|
||||
- 依赖包:见 `requirements_8080.txt`
|
||||
|
||||
## 📦 安装依赖
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
pip install -r requirements_8080.txt
|
||||
```
|
||||
|
||||
## 🌐 访问地址
|
||||
|
||||
启动成功后,可以通过以下地址访问:
|
||||
|
||||
- **本地访问**: http://localhost:8080
|
||||
- **API文档**: http://localhost:8080/docs
|
||||
- **健康检查**: http://localhost:8080/api/v1/health
|
||||
|
||||
## 🧪 测试命令
|
||||
|
||||
### 测试所有端点
|
||||
```bash
|
||||
python3 test_api_8080.py
|
||||
```
|
||||
|
||||
### 测试特定端点类型
|
||||
```bash
|
||||
# 只测试基础端点
|
||||
python3 test_api_8080.py --basic
|
||||
|
||||
# 只测试认证端点
|
||||
python3 test_api_8080.py --auth
|
||||
|
||||
# 只测试文件端点
|
||||
python3 test_api_8080.py --files
|
||||
```
|
||||
|
||||
### 指定不同的API地址
|
||||
```bash
|
||||
python3 test_api_8080.py --url http://192.168.1.100:8080
|
||||
```
|
||||
|
||||
### 启动前等待时间
|
||||
```bash
|
||||
python3 test_api_8080.py --wait 5 # 等待5秒后开始测试
|
||||
```
|
||||
|
||||
## 📊 测试结果说明
|
||||
|
||||
- ✅ **成功**: 端点正常响应
|
||||
- 🔌 **连接失败**: 无法连接到服务器
|
||||
- ⏰ **超时**: 请求超时
|
||||
- ❌ **其他错误**: 各种错误情况
|
||||
|
||||
## 🔍 故障排除
|
||||
|
||||
### 端口被占用
|
||||
```bash
|
||||
# 查看占用端口的进程
|
||||
lsof -i :8080
|
||||
|
||||
# 停止进程
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
### 依赖问题
|
||||
```bash
|
||||
# 安装基础依赖
|
||||
pip install fastapi uvicorn requests
|
||||
|
||||
# 或安装所有依赖
|
||||
pip install -r requirements_8080.txt
|
||||
```
|
||||
|
||||
### 模块导入错误
|
||||
如果遇到模块导入错误,脚本会自动切换到简化模式,提供基础的API功能。
|
||||
|
||||
## 🎯 预期结果
|
||||
|
||||
正常运行时,你应该看到:
|
||||
|
||||
1. **服务器启动信息**
|
||||
```
|
||||
🚀 启动云盘应用服务...
|
||||
📍 本地访问:
|
||||
根路径: http://localhost:8080
|
||||
API文档: http://localhost:8080/docs
|
||||
```
|
||||
|
||||
2. **API测试结果**
|
||||
```
|
||||
🧪 开始API测试 - 端口8080
|
||||
📊 测试报告
|
||||
总测试数: 6
|
||||
成功: 6
|
||||
失败: 0
|
||||
成功率: 100.0%
|
||||
🎉 所有测试通过!API服务运行正常
|
||||
```
|
||||
|
||||
3. **API响应示例**
|
||||
```json
|
||||
{
|
||||
"message": "云盘应用 API",
|
||||
"version": "1.0.1",
|
||||
"docs": "/docs",
|
||||
"health": "/api/v1/health"
|
||||
}
|
||||
```
|
||||
|
||||
## 📞 使用curl测试
|
||||
|
||||
你也可以使用curl命令直接测试:
|
||||
|
||||
```bash
|
||||
# 测试根路径
|
||||
curl http://localhost:8080/
|
||||
|
||||
# 测试健康检查
|
||||
curl http://localhost:8080/api/v1/health
|
||||
|
||||
# 测试API文档
|
||||
curl -I http://localhost:8080/docs
|
||||
```
|
||||
|
||||
现在你可以选择任何一种方式启动和测试你的云盘应用在端口8080上!
|
||||
@@ -1,257 +0,0 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# 项目根目录
|
||||
ROOT_DIR = Path.cwd()
|
||||
|
||||
# 需要包含的数据文件
|
||||
datas = [
|
||||
(str(ROOT_DIR / 'app'), 'app'), # 包含整个app目录
|
||||
('.env.example', '.'), # 包含环境配置示例文件
|
||||
]
|
||||
|
||||
# 可选数据文件(如果存在才包含)
|
||||
optional_files = [
|
||||
('database', 'database'), # 包含数据库相关文件
|
||||
]
|
||||
|
||||
# 添加可选数据文件
|
||||
for src, dst in optional_files:
|
||||
src_path = ROOT_DIR / src
|
||||
if src_path.exists():
|
||||
datas.append((src, dst))
|
||||
print(f"包含可选数据文件: {src}")
|
||||
else:
|
||||
print(f"跳过可选数据文件: {src} (不存在)")
|
||||
|
||||
# 隐式导入的模块
|
||||
hiddenimports = [
|
||||
# FastAPI相关
|
||||
'fastapi',
|
||||
'fastapi.templating',
|
||||
'fastapi.staticfiles',
|
||||
'fastapi.middleware',
|
||||
'fastapi.middleware.cors',
|
||||
'fastapi.responses',
|
||||
'fastapi.exceptions',
|
||||
# Uvicorn相关
|
||||
'uvicorn',
|
||||
'uvicorn.lifespan.on',
|
||||
'uvicorn.lifespan.off',
|
||||
'uvicorn.lifespan.on_startup',
|
||||
'uvicorn.lifespan.on_shutdown',
|
||||
'uvicorn.protocols.http.auto',
|
||||
'uvicorn.protocols.http.h11_impl',
|
||||
'uvicorn.protocols.websockets.auto',
|
||||
'uvicorn.protocols.websockets.wsproto_impl',
|
||||
'uvicorn.logging',
|
||||
'uvicorn.main',
|
||||
# Starlette相关
|
||||
'starlette',
|
||||
'starlette.applications',
|
||||
'starlette.middleware',
|
||||
'starlette.middleware.cors',
|
||||
'starlette.routing',
|
||||
'starlette.responses',
|
||||
'starlette.staticfiles',
|
||||
'starlette.exceptions',
|
||||
# Pydantic相关
|
||||
'pydantic',
|
||||
'pydantic.main',
|
||||
'pydantic.fields',
|
||||
'pydantic_settings',
|
||||
'pydantic.networks',
|
||||
'pydantic.types',
|
||||
'pydantic.validators',
|
||||
'pydantic.json_schema',
|
||||
# SQLAlchemy相关
|
||||
'sqlalchemy',
|
||||
'sqlalchemy.dialects',
|
||||
'sqlalchemy.dialects.mysql',
|
||||
'sqlalchemy.engine',
|
||||
'sqlalchemy.ext.declarative',
|
||||
'sqlalchemy.orm',
|
||||
'sqlalchemy.sql',
|
||||
'sqlalchemy.pool',
|
||||
'sqlalchemy.event',
|
||||
# 认证相关
|
||||
'passlib',
|
||||
'passlib.hash',
|
||||
'passlib.hash.bcrypt',
|
||||
'passlib.context',
|
||||
'python_jose',
|
||||
'python_jose.jwk',
|
||||
'python_jose.jws',
|
||||
'python_jose.jwt',
|
||||
'python_jose.backends',
|
||||
'python_jose.backends.cryptography',
|
||||
'python_multipart',
|
||||
'multipart',
|
||||
'multipart.multipart',
|
||||
# 数据库驱动
|
||||
'pymysql',
|
||||
'pymysql.connections',
|
||||
'pymysql.cursors',
|
||||
'pymysql.charset',
|
||||
# Redis相关
|
||||
'redis',
|
||||
'redis.client',
|
||||
'redis.connection',
|
||||
'redis.exceptions',
|
||||
'redis.commands',
|
||||
'redis.asyncio',
|
||||
# HTTP客户端
|
||||
'httpx',
|
||||
'httpx.client',
|
||||
'httpx._client',
|
||||
'httpx._transports',
|
||||
'httpx._transports.default',
|
||||
# 工具库
|
||||
'loguru',
|
||||
'python_dotenv',
|
||||
'dotenv',
|
||||
'dotenv.main',
|
||||
# Alembic(数据库迁移)
|
||||
'alembic',
|
||||
'alembic.command',
|
||||
'alembic.config',
|
||||
'alembic.script',
|
||||
'alembic.runtime',
|
||||
'alembic.migration',
|
||||
# 其他依赖
|
||||
'email.utils',
|
||||
'email.mime',
|
||||
'yaml',
|
||||
'toml',
|
||||
'json',
|
||||
'base64',
|
||||
'hashlib',
|
||||
'datetime',
|
||||
'uuid',
|
||||
'os',
|
||||
'sys',
|
||||
'pathlib',
|
||||
'typing',
|
||||
'collections',
|
||||
'itertools',
|
||||
'functools',
|
||||
'time',
|
||||
'math',
|
||||
're',
|
||||
'socket',
|
||||
'threading',
|
||||
'asyncio',
|
||||
'concurrent.futures',
|
||||
# MySQL相关
|
||||
'cryptography',
|
||||
'cryptography.hazmat',
|
||||
'cryptography.hazmat.backends',
|
||||
'cryptography.hazmat.backends.openssl',
|
||||
'cryptography.hazmat.primitives',
|
||||
'cryptography.hazmat.primitives.hashes',
|
||||
'cryptography.hazmat.primitives.kdf',
|
||||
'cryptography.hazmat.primitives.ciphers',
|
||||
# Jinja2模板引擎(FastAPI可能用到)
|
||||
'jinja2',
|
||||
'jinja2.utils',
|
||||
'jinja2.environment',
|
||||
# 文件处理相关
|
||||
'mimetypes',
|
||||
'tempfile',
|
||||
'shutil',
|
||||
'gzip',
|
||||
'zipfile',
|
||||
# 命令行参数处理
|
||||
'argparse',
|
||||
'getopt',
|
||||
# 编码相关
|
||||
'codecs',
|
||||
'encodings',
|
||||
'encodings.utf_8',
|
||||
'encodings.ascii',
|
||||
'encodings.latin1',
|
||||
'encodings.cp1252',
|
||||
# 正则表达式
|
||||
'regex',
|
||||
# 随机数
|
||||
'random',
|
||||
'secrets',
|
||||
# 日期时间处理
|
||||
'calendar',
|
||||
'time',
|
||||
# 网络相关
|
||||
'urllib',
|
||||
'urllib.parse',
|
||||
'urllib.request',
|
||||
'http',
|
||||
'http.server',
|
||||
'socketserver',
|
||||
# 异步相关
|
||||
'asyncio.runners',
|
||||
'asyncio.events',
|
||||
'asyncio.locks',
|
||||
# 多进程
|
||||
'multiprocessing',
|
||||
'multiprocessing.pool',
|
||||
# 系统信号
|
||||
'signal',
|
||||
# 环境变量
|
||||
'environ',
|
||||
]
|
||||
|
||||
block_cipher = None
|
||||
|
||||
a = Analysis(
|
||||
['main.py'],
|
||||
pathex=[str(ROOT_DIR)],
|
||||
binaries=[],
|
||||
datas=datas,
|
||||
hiddenimports=hiddenimports,
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[
|
||||
# 排除不需要的大型库以减小体积
|
||||
'Pillow', 'PIL', 'numpy', 'scipy', 'matplotlib', 'pandas',
|
||||
'torch', 'tensorflow', 'keras', 'sklearn', 'opencv',
|
||||
'jupyter', 'notebook', 'ipython', 'sphinx', 'pytest',
|
||||
'setuptools', 'pip', 'wheel', 'twine',
|
||||
'PyQt5', 'PyQt6', 'PySide2', 'PySide6', 'tkinter',
|
||||
'gtk', 'wx', 'fltk', 'kivy',
|
||||
# 排除开发工具
|
||||
'black', 'flake8', 'mypy', 'pylint', 'isort',
|
||||
'pytest', 'unittest', 'doctest',
|
||||
# 排除数据库工具
|
||||
'psycopg2', 'cx_Oracle', 'sqlite3',
|
||||
],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='cloud-drive-server',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=True, # Linux下启用strip以减小体积
|
||||
upx=True, # 启用UPX压缩
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True, # 控制台应用,便于查看日志
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch='linux64', # 指定目标架构为64位Linux
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
@@ -1,258 +0,0 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
# 适用于没有共享库的Python环境的PyInstaller配置
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# 项目根目录
|
||||
ROOT_DIR = Path.cwd()
|
||||
|
||||
# 需要包含的数据文件
|
||||
datas = [
|
||||
(str(ROOT_DIR / 'app'), 'app'), # 包含整个app目录
|
||||
('.env.example', '.'), # 包含环境配置示例文件
|
||||
]
|
||||
|
||||
# 可选数据文件(如果存在才包含)
|
||||
optional_files = [
|
||||
('database', 'database'), # 包含数据库相关文件
|
||||
]
|
||||
|
||||
# 添加可选数据文件
|
||||
for src, dst in optional_files:
|
||||
src_path = ROOT_DIR / src
|
||||
if src_path.exists():
|
||||
datas.append((src, dst))
|
||||
print(f"包含可选数据文件: {src}")
|
||||
else:
|
||||
print(f"跳过可选数据文件: {src} (不存在)")
|
||||
|
||||
# 隐式导入的模块
|
||||
hiddenimports = [
|
||||
# FastAPI相关
|
||||
'fastapi',
|
||||
'fastapi.templating',
|
||||
'fastapi.staticfiles',
|
||||
'fastapi.middleware',
|
||||
'fastapi.middleware.cors',
|
||||
'fastapi.responses',
|
||||
'fastapi.exceptions',
|
||||
# Uvicorn相关
|
||||
'uvicorn',
|
||||
'uvicorn.lifespan.on',
|
||||
'uvicorn.lifespan.off',
|
||||
'uvicorn.lifespan.on_startup',
|
||||
'uvicorn.lifespan.on_shutdown',
|
||||
'uvicorn.protocols.http.auto',
|
||||
'uvicorn.protocols.http.h11_impl',
|
||||
'uvicorn.protocols.websockets.auto',
|
||||
'uvicorn.protocols.websockets.wsproto_impl',
|
||||
'uvicorn.logging',
|
||||
'uvicorn.main',
|
||||
# Starlette相关
|
||||
'starlette',
|
||||
'starlette.applications',
|
||||
'starlette.middleware',
|
||||
'starlette.middleware.cors',
|
||||
'starlette.routing',
|
||||
'starlette.responses',
|
||||
'starlette.staticfiles',
|
||||
'starlette.exceptions',
|
||||
# Pydantic相关
|
||||
'pydantic',
|
||||
'pydantic.main',
|
||||
'pydantic.fields',
|
||||
'pydantic_settings',
|
||||
'pydantic.networks',
|
||||
'pydantic.types',
|
||||
'pydantic.validators',
|
||||
'pydantic.json_schema',
|
||||
# SQLAlchemy相关
|
||||
'sqlalchemy',
|
||||
'sqlalchemy.dialects',
|
||||
'sqlalchemy.dialects.mysql',
|
||||
'sqlalchemy.engine',
|
||||
'sqlalchemy.ext.declarative',
|
||||
'sqlalchemy.orm',
|
||||
'sqlalchemy.sql',
|
||||
'sqlalchemy.pool',
|
||||
'sqlalchemy.event',
|
||||
# 认证相关
|
||||
'passlib',
|
||||
'passlib.hash',
|
||||
'passlib.hash.bcrypt',
|
||||
'passlib.context',
|
||||
'python_jose',
|
||||
'python_jose.jwk',
|
||||
'python_jose.jws',
|
||||
'python_jose.jwt',
|
||||
'python_jose.backends',
|
||||
'python_jose.backends.cryptography',
|
||||
'python_multipart',
|
||||
'multipart',
|
||||
'multipart.multipart',
|
||||
# 数据库驱动
|
||||
'pymysql',
|
||||
'pymysql.connections',
|
||||
'pymysql.cursors',
|
||||
'pymysql.charset',
|
||||
# Redis相关
|
||||
'redis',
|
||||
'redis.client',
|
||||
'redis.connection',
|
||||
'redis.exceptions',
|
||||
'redis.commands',
|
||||
'redis.asyncio',
|
||||
# HTTP客户端
|
||||
'httpx',
|
||||
'httpx.client',
|
||||
'httpx._client',
|
||||
'httpx._transports',
|
||||
'httpx._transports.default',
|
||||
# 工具库
|
||||
'loguru',
|
||||
'python_dotenv',
|
||||
'dotenv',
|
||||
'dotenv.main',
|
||||
# Alembic(数据库迁移)
|
||||
'alembic',
|
||||
'alembic.command',
|
||||
'alembic.config',
|
||||
'alembic.script',
|
||||
'alembic.runtime',
|
||||
'alembic.migration',
|
||||
# 其他依赖
|
||||
'email.utils',
|
||||
'email.mime',
|
||||
'yaml',
|
||||
'toml',
|
||||
'json',
|
||||
'base64',
|
||||
'hashlib',
|
||||
'datetime',
|
||||
'uuid',
|
||||
'os',
|
||||
'sys',
|
||||
'pathlib',
|
||||
'typing',
|
||||
'collections',
|
||||
'itertools',
|
||||
'functools',
|
||||
'time',
|
||||
'math',
|
||||
're',
|
||||
'socket',
|
||||
'threading',
|
||||
'asyncio',
|
||||
'concurrent.futures',
|
||||
# MySQL相关
|
||||
'cryptography',
|
||||
'cryptography.hazmat',
|
||||
'cryptography.hazmat.backends',
|
||||
'cryptography.hazmat.backends.openssl',
|
||||
'cryptography.hazmat.primitives',
|
||||
'cryptography.hazmat.primitives.hashes',
|
||||
'cryptography.hazmat.primitives.kdf',
|
||||
'cryptography.hazmat.primitives.ciphers',
|
||||
# Jinja2模板引擎
|
||||
'jinja2',
|
||||
'jinja2.utils',
|
||||
'jinja2.environment',
|
||||
# 文件处理相关
|
||||
'mimetypes',
|
||||
'tempfile',
|
||||
'shutil',
|
||||
'gzip',
|
||||
'zipfile',
|
||||
# 命令行参数处理
|
||||
'argparse',
|
||||
'getopt',
|
||||
# 编码相关
|
||||
'codecs',
|
||||
'encodings',
|
||||
'encodings.utf_8',
|
||||
'encodings.ascii',
|
||||
'encodings.latin1',
|
||||
'encodings.cp1252',
|
||||
# 正则表达式
|
||||
'regex',
|
||||
# 随机数
|
||||
'random',
|
||||
'secrets',
|
||||
# 日期时间处理
|
||||
'calendar',
|
||||
'time',
|
||||
# 网络相关
|
||||
'urllib',
|
||||
'urllib.parse',
|
||||
'urllib.request',
|
||||
'http',
|
||||
'http.server',
|
||||
'socketserver',
|
||||
# 异步相关
|
||||
'asyncio.runners',
|
||||
'asyncio.events',
|
||||
'asyncio.locks',
|
||||
# 多进程
|
||||
'multiprocessing',
|
||||
'multiprocessing.pool',
|
||||
# 系统信号
|
||||
'signal',
|
||||
# 环境变量
|
||||
'environ',
|
||||
]
|
||||
|
||||
block_cipher = None
|
||||
|
||||
a = Analysis(
|
||||
['main.py'],
|
||||
pathex=[str(ROOT_DIR)],
|
||||
binaries=[],
|
||||
datas=datas,
|
||||
hiddenimports=hiddenimports,
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[
|
||||
# 排除不需要的大型库以减小体积
|
||||
'Pillow', 'PIL', 'numpy', 'scipy', 'matplotlib', 'pandas',
|
||||
'torch', 'tensorflow', 'keras', 'sklearn', 'opencv',
|
||||
'jupyter', 'notebook', 'ipython', 'sphinx', 'pytest',
|
||||
'setuptools', 'pip', 'wheel', 'twine',
|
||||
'PyQt5', 'PyQt6', 'PySide2', 'PySide6', 'tkinter',
|
||||
'gtk', 'wx', 'fltk', 'kivy',
|
||||
# 排除开发工具
|
||||
'black', 'flake8', 'mypy', 'pylint', 'isort',
|
||||
'pytest', 'unittest', 'doctest',
|
||||
# 排除数据库工具
|
||||
'psycopg2', 'cx_Oracle', 'sqlite3',
|
||||
],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='cloud-drive-server',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False, # 关闭strip,避免在没有共享库的环境中出问题
|
||||
upx=False, # 关闭UPX,避免兼容性问题
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True, # 控制台应用,便于查看日志
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None, # 不指定目标架构,让PyInstaller自动处理
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
@@ -1,38 +0,0 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['test-main.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[('app', 'app'), ('.env.test', '.')],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='cloud-drive-server-test',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
@@ -1,60 +0,0 @@
|
||||
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
block_cipher = None
|
||||
|
||||
a = Analysis(
|
||||
['main.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[
|
||||
('app', 'app'),
|
||||
('uploads', 'uploads'),
|
||||
('logs', 'logs'),
|
||||
],
|
||||
hiddenimports=[
|
||||
'uvicorn',
|
||||
'fastapi',
|
||||
'sqlalchemy',
|
||||
'pymysql',
|
||||
'pydantic',
|
||||
'pydantic_settings',
|
||||
'redis',
|
||||
'passlib',
|
||||
'python_jose',
|
||||
'uvicorn.protocols.http.httptools_impl',
|
||||
],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='cloud-drive-server',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon=None
|
||||
)
|
||||
@@ -1,40 +0,0 @@
|
||||
[Unit]
|
||||
Description=Cloud Drive Backend Service
|
||||
Documentation=https://github.com/your-repo/cloud-drive
|
||||
After=network.target mysql.service redis.service
|
||||
Wants=mysql.service redis.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=cloud-drive
|
||||
Group=cloud-drive
|
||||
WorkingDirectory=/opt/cloud-drive
|
||||
ExecStart=/opt/cloud-drive/cloud-drive-server
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StartLimitInterval=60
|
||||
StartLimitBurst=3
|
||||
|
||||
# 环境变量
|
||||
Environment=PYTHONPATH=/opt/cloud-drive
|
||||
Environment=ENVIRONMENT=production
|
||||
|
||||
# 安全设置
|
||||
NoNewPrivileges=yes
|
||||
PrivateTmp=yes
|
||||
ProtectSystem=strict
|
||||
ProtectHome=yes
|
||||
ReadWritePaths=/opt/cloud-drive/logs /opt/cloud-drive/uploads
|
||||
|
||||
# 资源限制
|
||||
LimitNOFILE=65536
|
||||
LimitNPROC=4096
|
||||
|
||||
# 日志
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=cloud-drive
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,313 +0,0 @@
|
||||
# 云盘应用 Linux 环境部署指南
|
||||
|
||||
本文档介绍如何将云盘应用后端打包成 Docker 镜像并部署到 Linux 环境。
|
||||
|
||||
## 📋 部署前准备
|
||||
|
||||
### 1. 系统要求
|
||||
- Linux 操作系统(推荐 Ubuntu 20.04+ 或 CentOS 8+)
|
||||
- Docker 20.10+
|
||||
- Docker Compose 2.0+
|
||||
- 至少 2GB 内存
|
||||
- 至少 10GB 磁盘空间
|
||||
|
||||
### 2. 安装 Docker
|
||||
|
||||
#### Ubuntu/Debian:
|
||||
```bash
|
||||
# 更新包索引
|
||||
sudo apt-get update
|
||||
|
||||
# 安装必要的包
|
||||
sudo apt-get install ca-certificates curl gnupg lsb-release
|
||||
|
||||
# 添加 Docker 官方 GPG key
|
||||
sudo mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
|
||||
# 设置仓库
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
# 安装 Docker Engine
|
||||
sudo apt-get update
|
||||
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
```
|
||||
|
||||
#### CentOS/RHEL:
|
||||
```bash
|
||||
# 安装 yum-utils
|
||||
sudo yum install -y yum-utils
|
||||
|
||||
# 添加 Docker 仓库
|
||||
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||||
|
||||
# 安装 Docker Engine
|
||||
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
```
|
||||
|
||||
### 3. 启动 Docker 服务
|
||||
```bash
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
```
|
||||
|
||||
### 4. 将用户添加到 docker 组(可选)
|
||||
```bash
|
||||
sudo usermod -aG docker $USER
|
||||
# 重新登录或执行
|
||||
newgrp docker
|
||||
```
|
||||
|
||||
## 🚀 快速部署
|
||||
|
||||
### 方法一:使用自动部署脚本(推荐)
|
||||
|
||||
1. 将 backend 目录上传到服务器
|
||||
2. 进入 backend 目录
|
||||
3. 给脚本添加执行权限:
|
||||
```bash
|
||||
chmod +x build-docker.sh
|
||||
```
|
||||
4. 运行部署脚本:
|
||||
```bash
|
||||
# 完整部署(构建镜像 + 运行容器)
|
||||
./build-docker.sh
|
||||
|
||||
# 或者使用 Docker Compose 部署
|
||||
./build-docker.sh compose
|
||||
```
|
||||
|
||||
### 方法二:手动部署
|
||||
|
||||
1. **构建镜像**
|
||||
```bash
|
||||
docker build -t cloud-drive-backend:latest .
|
||||
```
|
||||
|
||||
2. **运行容器**
|
||||
```bash
|
||||
docker run -d \
|
||||
--name cloud-drive-backend \
|
||||
--restart unless-stopped \
|
||||
-p 8002:8002 \
|
||||
-v $(pwd)/uploads:/app/uploads \
|
||||
-v $(pwd)/logs:/app/logs \
|
||||
-e ENVIRONMENT=production \
|
||||
cloud-drive-backend:latest
|
||||
```
|
||||
|
||||
### 方法三:使用 Docker Compose
|
||||
|
||||
1. **配置环境变量**
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# 编辑 .env 文件,设置正确的配置
|
||||
```
|
||||
|
||||
2. **启动服务**
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## ⚙️ 配置说明
|
||||
|
||||
### 环境变量配置
|
||||
|
||||
创建 `.env` 文件:
|
||||
```bash
|
||||
# 数据库配置
|
||||
DATABASE_URL=mysql://username:password@mysql:3306/mytest_db
|
||||
MYSQL_ROOT_PASSWORD=your_root_password
|
||||
MYSQL_DATABASE=mytest_db
|
||||
MYSQL_USER=your_username
|
||||
MYSQL_PASSWORD=your_password
|
||||
|
||||
# Redis 配置
|
||||
REDIS_URL=redis://redis:6379/0
|
||||
|
||||
# 应用配置
|
||||
SECRET_KEY=your-production-secret-key
|
||||
CORS_ORIGINS=http://localhost:3003,https://yourdomain.com
|
||||
ENVIRONMENT=production
|
||||
```
|
||||
|
||||
### 端口配置
|
||||
- 应用端口:8002
|
||||
- MySQL 端口:3306
|
||||
- Redis 端口:6379
|
||||
|
||||
### 数据持久化
|
||||
- `./uploads` - 文件上传目录
|
||||
- `./logs` - 应用日志目录
|
||||
- `mysql_data` - MySQL 数据目录
|
||||
- `redis_data` - Redis 数据目录
|
||||
|
||||
## 🛠️ 常用命令
|
||||
|
||||
### 容器管理
|
||||
```bash
|
||||
# 查看容器状态
|
||||
./build-docker.sh status
|
||||
|
||||
# 查看容器日志
|
||||
./build-docker.sh logs
|
||||
|
||||
# 重启容器
|
||||
./build-docker.sh restart
|
||||
|
||||
# 停止容器
|
||||
./build-docker.sh stop
|
||||
|
||||
# 清理资源
|
||||
./build-docker.sh cleanup
|
||||
```
|
||||
|
||||
### Docker Compose 命令
|
||||
```bash
|
||||
# 查看服务状态
|
||||
docker-compose ps
|
||||
|
||||
# 查看日志
|
||||
docker-compose logs -f
|
||||
|
||||
# 重启服务
|
||||
docker-compose restart
|
||||
|
||||
# 停止服务
|
||||
docker-compose down
|
||||
|
||||
# 更新并重启
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
## 🔍 健康检查
|
||||
|
||||
应用包含内置的健康检查端点:
|
||||
- 端点:`http://localhost:8002/api/v1/health`
|
||||
- 检查间隔:30秒
|
||||
- 超时时间:30秒
|
||||
- 重试次数:3次
|
||||
|
||||
手动检查:
|
||||
```bash
|
||||
curl http://localhost:8002/api/v1/health
|
||||
```
|
||||
|
||||
## 🔧 故障排除
|
||||
|
||||
### 1. 容器无法启动
|
||||
```bash
|
||||
# 查看容器日志
|
||||
docker logs cloud-drive-backend
|
||||
|
||||
# 检查端口占用
|
||||
netstat -tulpn | grep 8002
|
||||
```
|
||||
|
||||
### 2. 数据库连接失败
|
||||
- 检查数据库服务是否运行
|
||||
- 验证连接字符串是否正确
|
||||
- 确认网络连通性
|
||||
|
||||
### 3. 文件上传问题
|
||||
- 检查 uploads 目录权限
|
||||
- 确认磁盘空间充足
|
||||
- 验证文件大小限制
|
||||
|
||||
### 4. 内存不足
|
||||
```bash
|
||||
# 检查内存使用
|
||||
free -h
|
||||
|
||||
# 检查容器资源使用
|
||||
docker stats
|
||||
```
|
||||
|
||||
## 📊 监控
|
||||
|
||||
### 日志监控
|
||||
```bash
|
||||
# 实时查看日志
|
||||
tail -f logs/app.log
|
||||
|
||||
# 查看错误日志
|
||||
grep ERROR logs/app.log
|
||||
```
|
||||
|
||||
### 性能监控
|
||||
```bash
|
||||
# 查看容器资源使用
|
||||
docker stats cloud-drive-backend
|
||||
|
||||
# 查看系统资源
|
||||
htop
|
||||
```
|
||||
|
||||
## 🔒 安全配置
|
||||
|
||||
### 1. 防火墙设置
|
||||
```bash
|
||||
# Ubuntu UFW
|
||||
sudo ufw allow 8002
|
||||
sudo ufw allow 22
|
||||
sudo ufw enable
|
||||
|
||||
# CentOS firewalld
|
||||
sudo firewall-cmd --permanent --add-port=8002/tcp
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
### 2. SSL/TLS 配置
|
||||
建议使用 Nginx 或 Caddy 作为反向代理来处理 HTTPS:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name yourdomain.com;
|
||||
|
||||
ssl_certificate /path/to/certificate.crt;
|
||||
ssl_certificate_key /path/to/private.key;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8002;
|
||||
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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📈 扩展部署
|
||||
|
||||
### 1. 负载均衡
|
||||
使用多个容器实例配合负载均衡器:
|
||||
|
||||
```yaml
|
||||
# docker-compose.scale.yml
|
||||
version: '3.8'
|
||||
services:
|
||||
app:
|
||||
image: cloud-drive-backend:latest
|
||||
scale: 3
|
||||
# ... 其他配置
|
||||
```
|
||||
|
||||
### 2. 集群部署
|
||||
使用 Docker Swarm 或 Kubernetes 进行集群部署。
|
||||
|
||||
## 📞 支持
|
||||
|
||||
如遇到问题,请:
|
||||
1. 查看本文档的故障排除部分
|
||||
2. 检查应用日志和 Docker 日志
|
||||
3. 确认所有配置正确
|
||||
4. 验证系统资源是否充足
|
||||
|
||||
---
|
||||
|
||||
**注意**: 生产环境部署前请务必:
|
||||
- 更改默认密码和密钥
|
||||
- 配置适当的备份策略
|
||||
- 设置监控和告警
|
||||
- 进行充分的测试
|
||||
@@ -1,382 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Linux环境部署脚本
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== 云盘后端Linux部署脚本 ==="
|
||||
|
||||
# 检查当前目录
|
||||
if [ ! -f "main.py" ]; then
|
||||
echo "错误: 请在包含main.py的项目根目录下运行此脚本"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 1. 检查Python环境
|
||||
echo "1. 检查Python环境..."
|
||||
if ! command -v python3 &> /dev/null; then
|
||||
echo "错误: 未找到python3,请先安装Python 3.8+"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Python版本: $(python3 --version)"
|
||||
|
||||
# 2. 创建虚拟环境
|
||||
echo "2. 创建Python虚拟环境..."
|
||||
if [ ! -d "venv" ]; then
|
||||
echo "正在创建新的虚拟环境..."
|
||||
python3 -m venv venv
|
||||
echo "✓ 虚拟环境创建成功"
|
||||
# 验证虚拟环境文件
|
||||
ls -la venv/bin/ | head -5
|
||||
else
|
||||
echo "✓ 虚拟环境已存在"
|
||||
# 检查虚拟环境是否完整
|
||||
if [ ! -f "venv/bin/activate" ] && [ ! -f "venv/Scripts/activate" ]; then
|
||||
echo "⚠ 虚拟环境不完整,正在重新创建..."
|
||||
rm -rf venv
|
||||
python3 -m venv venv
|
||||
echo "✓ 虚拟环境重新创建成功"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 3. 激活虚拟环境
|
||||
echo "3. 激活虚拟环境..."
|
||||
if [ -f "venv/bin/activate" ]; then
|
||||
source venv/bin/activate
|
||||
echo "✓ 虚拟环境已激活"
|
||||
elif [ -f "venv/Scripts/activate" ]; then
|
||||
source venv/Scripts/activate
|
||||
echo "✓ 虚拟环境已激活 (Windows兼容)"
|
||||
else
|
||||
echo "✗ 虚拟环境激活文件不存在,尝试重新创建虚拟环境..."
|
||||
rm -rf venv
|
||||
python3 -m venv venv
|
||||
if [ -f "venv/bin/activate" ]; then
|
||||
source venv/bin/activate
|
||||
echo "✓ 虚拟环境重新创建并激活成功"
|
||||
else
|
||||
echo "✗ 虚拟环境创建失败,请检查Python安装"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 4. 升级pip
|
||||
echo "4. 升级pip..."
|
||||
pip install --upgrade pip
|
||||
|
||||
# 5. 安装依赖
|
||||
echo "5. 安装Python依赖..."
|
||||
if [ -f "requirements.txt" ]; then
|
||||
pip install -r requirements.txt
|
||||
echo "✓ 依赖安装完成"
|
||||
else
|
||||
echo "警告: requirements.txt 不存在,尝试安装基础依赖"
|
||||
pip install fastapi uvicorn sqlalchemy pymysql redis python-jose passlib python-multipart pydantic pydantic-settings httpx python-dotenv loguru alembic
|
||||
fi
|
||||
|
||||
# 6. 创建必要目录
|
||||
echo "6. 创建必要目录..."
|
||||
mkdir -p logs uploads
|
||||
echo "✓ 目录创建完成"
|
||||
|
||||
# 7. 配置环境变量
|
||||
echo "7. 配置环境变量..."
|
||||
if [ ! -f ".env" ]; then
|
||||
if [ -f ".env.example" ]; then
|
||||
cp .env.example .env
|
||||
echo "✓ 已从 .env.example 创建 .env 文件"
|
||||
echo "请编辑 .env 文件配置数据库连接等参数"
|
||||
echo "编辑命令: nano .env"
|
||||
else
|
||||
echo "警告: .env.example 不存在,创建默认配置"
|
||||
cat > .env << EOF
|
||||
# 基础配置
|
||||
ENVIRONMENT=production
|
||||
DEBUG=false
|
||||
|
||||
# 数据库配置
|
||||
DATABASE_URL=mysql+pymysql://用户名:密码@localhost:3306/数据库名
|
||||
|
||||
# Redis配置
|
||||
REDIS_URL=redis://localhost:6379
|
||||
|
||||
# JWT配置
|
||||
JWT_SECRET_KEY=your-super-secret-jwt-key-change-in-production
|
||||
JWT_ALGORITHM=HS256
|
||||
JWT_EXPIRE_MINUTES=30
|
||||
|
||||
# 文件上传配置
|
||||
UPLOAD_DIR=uploads
|
||||
MAX_FILE_SIZE=10485760
|
||||
|
||||
# CORS配置
|
||||
ALLOWED_HOSTS=["*"]
|
||||
EOF
|
||||
echo "✓ 已创建默认 .env 文件"
|
||||
fi
|
||||
else
|
||||
echo "✓ .env 文件已存在"
|
||||
fi
|
||||
|
||||
# 8. 创建启动脚本
|
||||
echo "8. 创建启动脚本..."
|
||||
cat > start.sh << 'STARTEOF'
|
||||
#!/bin/bash
|
||||
# 云盘后端启动脚本
|
||||
|
||||
# 进入脚本所在目录
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# 激活虚拟环境
|
||||
if [ -d "venv" ]; then
|
||||
source venv/bin/activate
|
||||
echo "✓ 虚拟环境已激活"
|
||||
else
|
||||
echo "错误: 虚拟环境不存在,请先运行部署脚本"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查环境文件
|
||||
if [ ! -f ".env" ]; then
|
||||
echo "错误: .env 文件不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建必要目录
|
||||
mkdir -p logs uploads
|
||||
|
||||
# 启动服务
|
||||
echo "启动云盘后端服务..."
|
||||
echo "服务地址: http://localhost:8000"
|
||||
echo "API文档: http://localhost:8000/docs"
|
||||
echo "按 Ctrl+C 停止服务"
|
||||
echo ""
|
||||
|
||||
python main.py
|
||||
STARTEOF
|
||||
|
||||
chmod +x start.sh
|
||||
echo "✓ 启动脚本创建完成: start.sh"
|
||||
|
||||
# 9. 创建停止脚本
|
||||
echo "9. 创建停止脚本..."
|
||||
cat > stop.sh << 'STOPEOF'
|
||||
#!/bin/bash
|
||||
# 云盘后端停止脚本
|
||||
|
||||
echo "停止云盘后端服务..."
|
||||
pkill -f "python main.py" || echo "服务未运行"
|
||||
echo "服务已停止"
|
||||
STOPEOF
|
||||
|
||||
chmod +x stop.sh
|
||||
echo "✓ 停止脚本创建完成: stop.sh"
|
||||
|
||||
# 10. 创建状态检查脚本
|
||||
echo "10. 创建状态检查脚本..."
|
||||
cat > status.sh << 'STATUSEOF'
|
||||
#!/bin/bash
|
||||
# 云盘后端状态检查脚本
|
||||
|
||||
if pgrep -f "python main.py" > /dev/null; then
|
||||
echo "✓ 云盘后端服务正在运行"
|
||||
echo "进程ID: $(pgrep -f 'python main.py')"
|
||||
echo "端口: 8000"
|
||||
echo "服务地址: http://localhost:8000"
|
||||
echo "API文档: http://localhost:8000/docs"
|
||||
|
||||
# 测试健康检查
|
||||
if curl -s http://localhost:8000/api/v1/health > /dev/null; then
|
||||
echo "✓ 服务响应正常"
|
||||
else
|
||||
echo "⚠ 服务运行但可能有问题"
|
||||
fi
|
||||
else
|
||||
echo "✗ 云盘后端服务未运行"
|
||||
echo "启动服务: ./start.sh"
|
||||
fi
|
||||
STATUSEOF
|
||||
|
||||
chmod +x status.sh
|
||||
echo "✓ 状态检查脚本创建完成: status.sh"
|
||||
|
||||
# 11. 创建systemd服务(可选)
|
||||
echo "11. 创建systemd服务..."
|
||||
|
||||
# 检查是否为root用户
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
# root用户创建系统级服务
|
||||
SERVICE_FILE="/etc/systemd/system/cloud-drive.service"
|
||||
echo "检测到root用户,创建系统级systemd服务..."
|
||||
|
||||
# 检查是否有写入权限
|
||||
if [ ! -w "/etc/systemd/system" ]; then
|
||||
echo "⚠ 警告: 没有写入/etc/systemd/system的权限,跳过systemd服务创建"
|
||||
echo "您可以手动创建服务文件或使用其他管理方式"
|
||||
else
|
||||
cat > "$SERVICE_FILE" << EOF
|
||||
[Unit]
|
||||
Description=Cloud Drive Backend Service
|
||||
Documentation=https://github.com/your-repo/cloud-drive
|
||||
After=network.target mysql.service redis.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=$(pwd)
|
||||
Environment=PATH=$(pwd)/venv/bin
|
||||
ExecStart=$(pwd)/venv/bin/python $(pwd)/main.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=cloud-drive
|
||||
|
||||
# 环境变量
|
||||
EnvironmentFile=$(pwd)/.env
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# 重载systemd服务
|
||||
systemctl daemon-reload
|
||||
echo "✓ 系统级systemd服务已创建"
|
||||
echo "启用服务: systemctl enable cloud-drive"
|
||||
echo "启动服务: systemctl start cloud-drive"
|
||||
echo "查看状态: systemctl status cloud-drive"
|
||||
echo "查看日志: journalctl -u cloud-drive -f"
|
||||
fi
|
||||
else
|
||||
# 普通用户创建用户级服务
|
||||
echo "为普通用户创建systemd用户服务..."
|
||||
|
||||
# 创建用户systemd目录
|
||||
USER_SERVICE_DIR="$HOME/.config/systemd/user"
|
||||
|
||||
# 检查并创建目录
|
||||
if [ ! -d "$USER_SERVICE_DIR" ]; then
|
||||
echo "创建用户systemd目录: $USER_SERVICE_DIR"
|
||||
mkdir -p "$USER_SERVICE_DIR" 2>/dev/null || {
|
||||
echo "⚠ 无法创建systemd用户目录,尝试使用临时目录..."
|
||||
USER_SERVICE_DIR="/tmp/cloud-drive-systemd"
|
||||
mkdir -p "$USER_SERVICE_DIR"
|
||||
echo "临时目录: $USER_SERVICE_DIR"
|
||||
}
|
||||
fi
|
||||
|
||||
SERVICE_FILE="$USER_SERVICE_DIR/cloud-drive.service"
|
||||
|
||||
# 检查是否有写入权限
|
||||
if [ ! -w "$USER_SERVICE_DIR" ]; then
|
||||
echo "⚠ 警告: 没有写入$USER_SERVICE_DIR的权限,尝试修复权限..."
|
||||
chmod 755 "$USER_SERVICE_DIR" 2>/dev/null || {
|
||||
echo "无法修复权限,尝试使用/tmp目录..."
|
||||
USER_SERVICE_DIR="/tmp/cloud-drive-systemd"
|
||||
mkdir -p "$USER_SERVICE_DIR"
|
||||
SERVICE_FILE="$USER_SERVICE_DIR/cloud-drive.service"
|
||||
echo "使用临时目录创建服务文件: $SERVICE_FILE"
|
||||
}
|
||||
fi
|
||||
|
||||
if [ -w "$USER_SERVICE_DIR" ]; then
|
||||
echo "✓ 确认有写入权限: $USER_SERVICE_DIR"
|
||||
cat > "$SERVICE_FILE" << EOF
|
||||
[Unit]
|
||||
Description=Cloud Drive Backend Service
|
||||
Documentation=https://github.com/your-repo/cloud-drive
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=$(pwd)
|
||||
ExecStart=$(pwd)/venv/bin/python $(pwd)/main.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=cloud-drive
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
|
||||
# 重载systemd用户服务
|
||||
systemctl --user daemon-reload 2>/dev/null || echo "⚠ 用户systemd重载失败,可能需要手动重载"
|
||||
echo "✓ systemd用户服务已创建"
|
||||
echo "启用服务: systemctl --user enable cloud-drive"
|
||||
echo "启动服务: systemctl --user start cloud-drive"
|
||||
echo "查看状态: systemctl --user status cloud-drive"
|
||||
echo "查看日志: journalctl --user -u cloud-drive -f"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 创建通用的启动脚本作为备用
|
||||
echo "创建备用启动脚本..."
|
||||
cat > systemd_start.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# systemd服务启动脚本
|
||||
|
||||
echo "Cloud Drive Backend systemd服务管理"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
echo "系统级服务命令:"
|
||||
echo "启用服务: systemctl enable cloud-drive"
|
||||
echo "启动服务: systemctl start cloud-drive"
|
||||
echo "停止服务: systemctl stop cloud-drive"
|
||||
echo "重启服务: systemctl restart cloud-drive"
|
||||
echo "查看状态: systemctl status cloud-drive"
|
||||
echo "查看日志: journalctl -u cloud-drive -f"
|
||||
else
|
||||
echo "用户级服务命令:"
|
||||
echo "启用服务: systemctl --user enable cloud-drive"
|
||||
echo "启动服务: systemctl --user start cloud-drive"
|
||||
echo "停止服务: systemctl --user stop cloud-drive"
|
||||
echo "重启服务: systemctl --user restart cloud-drive"
|
||||
echo "查看状态: systemctl --user status cloud-drive"
|
||||
echo "查看日志: journalctl --user -u cloud-drive -f"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "如果systemd服务不可用,可以使用手动管理:"
|
||||
echo "启动服务: ./start.sh"
|
||||
echo "停止服务: ./stop.sh"
|
||||
echo "查看状态: ./status.sh"
|
||||
EOF
|
||||
|
||||
chmod +x systemd_start.sh
|
||||
echo "✓ 备用启动脚本创建完成: systemd_start.sh"
|
||||
|
||||
# 12. 完成提示
|
||||
echo ""
|
||||
echo "=== 部署完成 ==="
|
||||
echo "当前目录: $(pwd)"
|
||||
echo ""
|
||||
echo "快速启动方式:"
|
||||
echo "1. 手动启动: ./start.sh"
|
||||
echo "2. 查看状态: ./status.sh"
|
||||
echo "3. 停止服务: ./stop.sh"
|
||||
echo ""
|
||||
echo "systemd服务方式:"
|
||||
echo "1. 启用服务: systemctl --user enable cloud-drive"
|
||||
echo "2. 启动服务: systemctl --user start cloud-drive"
|
||||
echo "3. 查看状态: systemctl --user status cloud-drive"
|
||||
echo "4. 查看日志: journalctl --user -u cloud-drive -f"
|
||||
echo ""
|
||||
echo "访问地址:"
|
||||
echo "- 服务地址: http://localhost:8000"
|
||||
echo "- API文档: http://localhost:8000/docs"
|
||||
echo "- 健康检查: http://localhost:8000/api/v1/health"
|
||||
echo ""
|
||||
echo "配置文件: .env"
|
||||
echo "日志目录: logs/"
|
||||
echo "上传目录: uploads/"
|
||||
echo ""
|
||||
echo "注意: 请确保数据库和Redis服务已启动并正确配置"
|
||||
|
||||
# 13. 自动启动服务
|
||||
echo ""
|
||||
echo "=== 正在启动服务 ==="
|
||||
echo "启动云盘后端服务..."
|
||||
./start.sh
|
||||
@@ -1,38 +0,0 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['main.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='main',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
@@ -1,32 +0,0 @@
|
||||
# Web框架
|
||||
fastapi==0.104.1
|
||||
uvicorn[standard]==0.24.0
|
||||
|
||||
# 数据库
|
||||
sqlalchemy==2.0.23
|
||||
pymysql==1.1.0
|
||||
alembic==1.12.1
|
||||
|
||||
# Redis
|
||||
redis==5.0.1
|
||||
|
||||
# 认证和安全
|
||||
python-jose[cryptography]==3.3.0
|
||||
passlib[bcrypt]==1.7.4
|
||||
python-multipart==0.0.6
|
||||
|
||||
# 数据验证
|
||||
pydantic==2.5.0
|
||||
pydantic-settings==2.1.0
|
||||
|
||||
# HTTP客户端
|
||||
httpx==0.25.2
|
||||
|
||||
# 工具库
|
||||
python-dotenv==1.0.0
|
||||
|
||||
# 邮件验证
|
||||
email-validator==2.1.0
|
||||
|
||||
# 生产环境优化
|
||||
gunicorn==21.2.0
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 快速部署脚本
|
||||
|
||||
echo "=== 快速部署云盘后端 ==="
|
||||
|
||||
# 基础检查
|
||||
if [ ! -f "main.py" ]; then
|
||||
echo "错误: 请在包含main.py的目录运行"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建虚拟环境
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# 安装依赖
|
||||
pip install fastapi uvicorn sqlalchemy pymysql redis python-jose passlib python-multipart pydantic pydantic-settings httpx python-dotenv loguru
|
||||
|
||||
# 配置环境
|
||||
if [ ! -f ".env" ]; then
|
||||
cat > .env << EOF
|
||||
ENVIRONMENT=production
|
||||
DEBUG=false
|
||||
DATABASE_URL=mysql+pymysql://root:password@localhost:3306/test_db
|
||||
REDIS_URL=redis://localhost:6379
|
||||
JWT_SECRET_KEY=your-secret-key-here
|
||||
JWT_EXPIRE_MINUTES=30
|
||||
UPLOAD_DIR=uploads
|
||||
MAX_FILE_SIZE=10485760
|
||||
ALLOWED_HOSTS=["*"]
|
||||
EOF
|
||||
echo "✓ 已创建 .env 配置文件"
|
||||
fi
|
||||
|
||||
# 创建目录
|
||||
mkdir -p logs uploads
|
||||
|
||||
# 启动服务
|
||||
echo "启动服务..."
|
||||
python main.py
|
||||
@@ -1,218 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 快速部署脚本 - 修复虚拟环境问题
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== 云盘后端快速部署脚本 ==="
|
||||
|
||||
# 检查当前目录
|
||||
if [ ! -f "main.py" ]; then
|
||||
echo "错误: 请在包含main.py的项目根目录下运行此脚本"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "当前目录: $(pwd)"
|
||||
|
||||
# 1. 检查Python环境
|
||||
echo "1. 检查Python环境..."
|
||||
if ! command -v python3 &> /dev/null; then
|
||||
echo "错误: 未找到python3,请先安装Python 3.8+"
|
||||
exit 1
|
||||
fi
|
||||
echo "✓ Python版本: $(python3 --version)"
|
||||
|
||||
# 2. 创建必要目录
|
||||
echo "2. 创建必要目录..."
|
||||
mkdir -p logs uploads
|
||||
echo "✓ 目录创建完成"
|
||||
|
||||
# 3. 直接安装依赖(不使用虚拟环境)
|
||||
echo "3. 安装Python依赖(系统级)..."
|
||||
echo "注意: 这将在系统级别安装依赖包"
|
||||
|
||||
# 检查是否为root用户
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
echo "检测到root用户,使用pip3安装..."
|
||||
pip3 install --upgrade pip
|
||||
|
||||
# 先安装email-validator
|
||||
echo "安装email-validator..."
|
||||
pip3 install email-validator
|
||||
|
||||
if [ -f "requirements.txt" ]; then
|
||||
echo "从requirements.txt安装依赖..."
|
||||
pip3 install -r requirements.txt
|
||||
else
|
||||
echo "安装基础依赖包..."
|
||||
pip3 install fastapi uvicorn sqlalchemy pymysql redis python-jose passlib python-multipart pydantic pydantic-settings httpx python-dotenv loguru alembic bcrypt
|
||||
fi
|
||||
else
|
||||
echo "使用用户级pip安装..."
|
||||
|
||||
# 检查是否有用户目录写入权限
|
||||
USER_LOCAL="$HOME/.local"
|
||||
if [ ! -w "$USER_LOCAL" ]; then
|
||||
echo "⚠ 用户目录无写入权限,尝试使用系统级安装..."
|
||||
pip3 install --upgrade pip
|
||||
pip3 install email-validator
|
||||
if [ -f "requirements.txt" ]; then
|
||||
pip3 install -r requirements.txt
|
||||
else
|
||||
pip3 install fastapi uvicorn sqlalchemy pymysql redis python-jose passlib python-multipart pydantic pydantic-settings httpx python-dotenv loguru alembic bcrypt
|
||||
fi
|
||||
else
|
||||
pip3 install --user --upgrade pip
|
||||
|
||||
# 先安装email-validator
|
||||
echo "安装email-validator..."
|
||||
pip3 install --user email-validator
|
||||
|
||||
if [ -f "requirements.txt" ]; then
|
||||
echo "从requirements.txt安装依赖..."
|
||||
pip3 install --user -r requirements.txt
|
||||
else
|
||||
echo "安装基础依赖包..."
|
||||
pip3 install --user fastapi uvicorn sqlalchemy pymysql redis python-jose passlib python-multipart pydantic pydantic-settings httpx python-dotenv loguru alembic bcrypt
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✓ 依赖安装完成"
|
||||
|
||||
# 4. 配置环境变量
|
||||
echo "4. 配置环境变量..."
|
||||
if [ ! -f ".env" ]; then
|
||||
echo "创建默认 .env 文件..."
|
||||
cat > .env << EOF
|
||||
# 基础配置
|
||||
ENVIRONMENT=production
|
||||
DEBUG=false
|
||||
|
||||
# 数据库配置
|
||||
DATABASE_URL=mysql+pymysql://用户名:密码@localhost:3306/数据库名
|
||||
|
||||
# Redis配置
|
||||
REDIS_URL=redis://localhost:6379
|
||||
|
||||
# JWT配置
|
||||
JWT_SECRET_KEY=your-super-secret-jwt-key-change-in-production-$(date +%s)
|
||||
JWT_ALGORITHM=HS256
|
||||
JWT_EXPIRE_MINUTES=30
|
||||
|
||||
# 文件上传配置
|
||||
UPLOAD_DIR=uploads
|
||||
MAX_FILE_SIZE=10485760
|
||||
|
||||
# CORS配置
|
||||
ALLOWED_HOSTS=["*"]
|
||||
EOF
|
||||
echo "✓ 已创建默认 .env 文件"
|
||||
echo "请编辑 .env 文件配置数据库连接等参数"
|
||||
else
|
||||
echo "✓ .env 文件已存在"
|
||||
fi
|
||||
|
||||
# 5. 创建启动脚本
|
||||
echo "5. 创建启动脚本..."
|
||||
cat > start_service.sh << 'STARTEOF'
|
||||
#!/bin/bash
|
||||
# 云盘后端启动脚本
|
||||
|
||||
# 进入脚本所在目录
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# 检查环境文件
|
||||
if [ ! -f ".env" ]; then
|
||||
echo "错误: .env 文件不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建必要目录
|
||||
mkdir -p logs uploads
|
||||
|
||||
# 启动服务
|
||||
echo "启动云盘后端服务..."
|
||||
echo "服务地址: http://localhost:8002"
|
||||
echo "API文档: http://localhost:8002/docs"
|
||||
echo "按 Ctrl+C 停止服务"
|
||||
echo ""
|
||||
|
||||
python3 main.py
|
||||
STARTEOF
|
||||
|
||||
chmod +x start_service.sh
|
||||
echo "✓ 启动脚本创建完成: start_service.sh"
|
||||
|
||||
# 6. 创建停止脚本
|
||||
echo "6. 创建停止脚本..."
|
||||
cat > stop_service.sh << 'STOPEOF'
|
||||
#!/bin/bash
|
||||
# 云盘后端停止脚本
|
||||
|
||||
echo "停止云盘后端服务..."
|
||||
pkill -f "python3 main.py" || echo "服务未运行"
|
||||
echo "服务已停止"
|
||||
STOPEOF
|
||||
|
||||
chmod +x stop_service.sh
|
||||
echo "✓ 停止脚本创建完成: stop_service.sh"
|
||||
|
||||
# 7. 创建状态检查脚本
|
||||
echo "7. 创建状态检查脚本..."
|
||||
cat > check_status.sh << 'STATUSEOF'
|
||||
#!/bin/bash
|
||||
# 云盘后端状态检查脚本
|
||||
|
||||
if pgrep -f "python3 main.py" > /dev/null; then
|
||||
echo "✓ 云盘后端服务正在运行"
|
||||
echo "进程ID: $(pgrep -f 'python3 main.py')"
|
||||
echo "端口: 8002"
|
||||
echo "服务地址: http://localhost:8002"
|
||||
echo "API文档: http://localhost:8002/docs"
|
||||
|
||||
# 测试健康检查
|
||||
if command -v curl &> /dev/null; then
|
||||
if curl -s http://localhost:8002/api/v1/health > /dev/null; then
|
||||
echo "✓ 服务响应正常"
|
||||
else
|
||||
echo "⚠ 服务运行但可能有问题"
|
||||
fi
|
||||
else
|
||||
echo "⚠ curl命令不可用,无法测试服务响应"
|
||||
fi
|
||||
else
|
||||
echo "✗ 云盘后端服务未运行"
|
||||
echo "启动服务: ./start_service.sh"
|
||||
fi
|
||||
STATUSEOF
|
||||
|
||||
chmod +x check_status.sh
|
||||
echo "✓ 状态检查脚本创建完成: check_status.sh"
|
||||
|
||||
# 8. 完成提示
|
||||
echo ""
|
||||
echo "=== 快速部署完成 ==="
|
||||
echo "当前目录: $(pwd)"
|
||||
echo ""
|
||||
echo "管理命令:"
|
||||
echo "1. 启动服务: ./start_service.sh"
|
||||
echo "2. 停止服务: ./stop_service.sh"
|
||||
echo "3. 查看状态: ./check_status.sh"
|
||||
echo ""
|
||||
echo "访问地址:"
|
||||
echo "- 服务地址: http://localhost:8002"
|
||||
echo "- API文档: http://localhost:8002/docs"
|
||||
echo "- 健康检查: http://localhost:8002/api/v1/health"
|
||||
echo ""
|
||||
echo "配置文件: .env"
|
||||
echo "日志目录: logs/"
|
||||
echo "上传目录: uploads/"
|
||||
echo ""
|
||||
echo "注意: 请确保数据库和Redis服务已启动并正确配置"
|
||||
|
||||
# 9. 自动启动服务
|
||||
echo ""
|
||||
echo "=== 正在启动服务 ==="
|
||||
echo "启动云盘后端服务..."
|
||||
./start_service.sh
|
||||
@@ -1,19 +0,0 @@
|
||||
# PyInstaller打包所需的依赖
|
||||
pyinstaller>=5.0.0,<7.0.0
|
||||
setuptools>=65.0.0
|
||||
|
||||
# 应用运行时依赖
|
||||
fastapi==0.104.1
|
||||
uvicorn[standard]==0.24.0
|
||||
sqlalchemy==2.0.23
|
||||
pymysql==1.1.0
|
||||
alembic==1.12.1
|
||||
redis==5.0.1
|
||||
python-jose[cryptography]==3.3.0
|
||||
passlib[bcrypt]==1.7.4
|
||||
python-multipart==0.0.6
|
||||
pydantic==2.5.0
|
||||
pydantic-settings==2.1.0
|
||||
httpx==0.25.2
|
||||
python-dotenv==1.0.0
|
||||
loguru>=0.7.0
|
||||
@@ -1,11 +0,0 @@
|
||||
# 开发依赖
|
||||
pytest==7.4.3
|
||||
pytest-asyncio==0.21.1
|
||||
httpx==0.25.2
|
||||
pytest-cov==4.1.0
|
||||
black==23.11.0
|
||||
isort==5.12.0
|
||||
flake8==6.1.0
|
||||
|
||||
# 基础依赖
|
||||
-r requirements.txt
|
||||
@@ -1,22 +0,0 @@
|
||||
# 云盘应用依赖 - 端口8080版本
|
||||
fastapi==0.104.1
|
||||
uvicorn[standard]==0.24.0
|
||||
requests==2.31.0
|
||||
python-dotenv==1.0.0
|
||||
loguru>=0.7.0
|
||||
|
||||
# 数据库相关 (如果需要完整功能)
|
||||
sqlalchemy==2.0.23
|
||||
pymysql==1.1.0
|
||||
|
||||
# 认证相关
|
||||
python-jose[cryptography]==3.3.0
|
||||
passlib[bcrypt]==1.7.4
|
||||
python-multipart==0.0.6
|
||||
|
||||
# 数据验证
|
||||
pydantic==2.5.0
|
||||
pydantic-settings==2.1.0
|
||||
|
||||
# HTTP客户端
|
||||
httpx==0.25.2
|
||||
@@ -1,3 +0,0 @@
|
||||
# 简化版依赖 - 用于测试基础功能
|
||||
fastapi==0.104.1
|
||||
uvicorn[standard]==0.24.0
|
||||
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
||||
测试文件写入
|
||||
时间: nt.times_result(user=0.015625, system=0.015625, children_user=0.0, children_system=0.0, elapsed=0.0)
|
||||
@@ -1 +0,0 @@
|
||||
test content
|
||||
Reference in New Issue
Block a user