#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 云盘后端Linux打包脚本 使用PyInstaller将后端应用打包成Linux可执行文件 """ import os import sys import shutil import subprocess from pathlib import Path import argparse def check_python_version(): """检查Python版本""" if sys.version_info < (3, 8): print("错误: 需要Python 3.8或更高版本") sys.exit(1) print(f"[OK] Python版本: {sys.version}") def check_dependencies(): """检查必要的依赖""" try: import PyInstaller print(f"[OK] PyInstaller版本: {PyInstaller.__version__}") except ImportError: print("错误: 未安装PyInstaller") print("请运行: pip install pyinstaller") sys.exit(1) def clean_build_dirs(): """清理之前的构建目录""" dirs_to_clean = ['build', 'dist', '__pycache__'] for dir_name in dirs_to_clean: if os.path.exists(dir_name): print(f"清理目录: {dir_name}") shutil.rmtree(dir_name) # 清理Python缓存文件 for root, dirs, files in os.walk('.'): for file in files: if file.endswith('.pyc') or file.endswith('.pyo'): os.remove(os.path.join(root, file)) if '__pycache__' in dirs: shutil.rmtree(os.path.join(root, '__pycache__')) def create_spec_file(): """创建或更新PyInstaller规格文件""" # 直接使用现有的build.spec文件 print("[OK] build.spec 文件已存在,跳过创建") def run_pyinstaller(): """运行PyInstaller进行打包""" print("开始打包...") try: # 使用spec文件进行打包 cmd = ['pyinstaller', '--clean', 'build.spec'] result = subprocess.run(cmd, check=True, capture_output=True, text=True) print("[OK] PyInstaller执行成功") if result.stdout: print("输出:", result.stdout) except subprocess.CalledProcessError as e: print(f"错误: PyInstaller执行失败: {e}") if e.stderr: print("错误输出:", e.stderr) sys.exit(1) def create_deployment_package(): """创建部署包""" dist_dir = Path('dist') deploy_dir = Path('deploy') if deploy_dir.exists(): shutil.rmtree(deploy_dir) deploy_dir.mkdir() # 复制可执行文件 exe_file = dist_dir / 'cloud-drive-server' if exe_file.exists(): shutil.copy2(exe_file, deploy_dir) print(f"[OK] 复制可执行文件到 {deploy_dir}") # 复制配置文件 config_files = ['.env.example'] for config_file in config_files: if os.path.exists(config_file): shutil.copy2(config_file, deploy_dir) print(f"[OK] 复制配置文件 {config_file}") # 复制安装脚本 install_scripts = ['install.sh', 'install_user.sh'] for script in install_scripts: if os.path.exists(script): shutil.copy2(script, deploy_dir) os.chmod(deploy_dir / script, 0o755) print(f"[OK] 复制安装脚本 {script}") # 创建部署目录结构 (deploy_dir / 'logs').mkdir(exist_ok=True) (deploy_dir / 'uploads').mkdir(exist_ok=True) # 创建启动脚本 create_startup_script(deploy_dir) # 创建README create_readme(deploy_dir) print(f"[OK] 部署包创建完成: {deploy_dir.absolute()}") def create_startup_script(deploy_dir): """创建启动脚本""" # Linux启动脚本 startup_script = '''#!/bin/bash # 云盘后端服务启动脚本 # 设置环境变量 export PYTHONPATH=${PYTHONPATH}:$(dirname "$0") # 进入脚本所在目录 cd "$(dirname "$0")" # 检查环境文件 if [ ! -f ".env" ]; then echo "警告: .env 文件不存在,将使用默认配置" if [ -f ".env.example" ]; then cp .env.example .env echo "已复制 .env.example 为 .env,请根据需要修改配置" fi fi # 创建必要的目录 mkdir -p logs uploads # 启动服务 echo "启动云盘后端服务..." ./cloud-drive-server ''' script_path = deploy_dir / 'start.sh' with open(script_path, 'w', encoding='utf-8') as f: f.write(startup_script) # 设置执行权限 os.chmod(script_path, 0o755) print("[OK] 创建启动脚本 start.sh") def create_readme(deploy_dir): """创建部署说明文档""" readme_content = '''# 云盘后端服务部署说明 ## 文件说明 - `cloud-drive-server`: 主程序可执行文件 - `start.sh`: 启动脚本 - `install.sh`: 系统级安装脚本(需要sudo权限) - `install_user.sh`: 用户级安装脚本(无需sudo权限) - `.env.example`: 环境配置示例文件 ## 快速开始 ### 方法一:用户级安装(推荐,无需sudo权限) ```bash # 1. 运行用户级安装脚本 ./install_user.sh # 2. 配置环境变量 cd ~/cloud-drive cp .env.example .env nano .env # 编辑配置文件 # 3. 启动服务 ./start.sh # 4. 查看状态 ./status.sh ``` ### 方法二:系统级安装(需要sudo权限) ```bash # 1. 运行系统级安装脚本 sudo ./install.sh # 2. 启动服务 sudo systemctl start cloud-drive # 3. 查看状态 sudo systemctl status cloud-drive ``` ### 方法三:直接运行 ```bash # 1. 配置环境变量 cp .env.example .env nano .env # 编辑配置文件 # 2. 启动服务 chmod +x cloud-drive-server ./cloud-drive-server ``` ## 环境配置 主要配置项(.env文件): ```env # 数据库配置 DATABASE_URL=mysql+pymysql://用户名:密码@主机:端口/数据库名 # Redis配置 REDIS_URL=redis://主机:端口 # JWT配置 JWT_SECRET_KEY=你的密钥 JWT_EXPIRE_MINUTES=30 # 文件上传配置 UPLOAD_DIR=uploads MAX_FILE_SIZE=10485760 # 10MB ``` ## 访问服务 - API文档: http://localhost:8000/docs - 健康检查: http://localhost:8000/api/v1/health - 根路径: http://localhost:8000/ ## 系统要求 - Linux 64位系统 - MySQL 5.7+ 或 8.0+ - Redis (可选) - 至少512MB内存 - 至少100MB磁盘空间 ## 问题排查 1. **端口占用** - 默认端口8000,如需修改请编辑.env文件 2. **数据库连接失败** - 检查DATABASE_URL配置 - 确保数据库服务正在运行 3. **权限问题** - 确保程序有执行权限:`chmod +x cloud-drive-server` - 确保有写入logs和uploads目录的权限 4. **依赖缺失** - 如果出现模块缺失错误,请确保打包包含了所有依赖 - 可以尝试重新运行打包脚本 ## 日志 日志文件位置: - 用户级安装:`~/.local/share/cloud-drive/logs/app.log` - 系统级安装:`/opt/cloud-drive/logs/app.log` - 直接运行:`./logs/app.log` ''' readme_path = deploy_dir / 'README.md' with open(readme_path, 'w', encoding='utf-8') as f: f.write(readme_content) print("[OK] 创建部署说明文档 README.md") def main(): """主函数""" parser = argparse.ArgumentParser(description='云盘后端Linux打包工具') parser.add_argument('--clean', action='store_true', help='仅清理构建目录') parser.add_argument('--no-clean', action='store_true', help='跳过清理步骤') args = parser.parse_args() print("=== 云盘后端Linux打包工具 ===") print(f"当前目录: {os.getcwd()}") # 检查环境 check_python_version() check_dependencies() # 清理构建目录 if args.clean: clean_build_dirs() print("[OK] 清理完成") return if not args.no_clean: clean_build_dirs() # 创建规格文件 create_spec_file() # 运行打包 run_pyinstaller() # 创建部署包 create_deployment_package() print("\n=== 打包完成 ===") print("部署包位置: ./deploy/") print("请查看 ./deploy/README.md 了解部署说明") print("\n安装方式:") print("1. 用户级安装(推荐):./install_user.sh") print("2. 系统级安装:sudo ./install.sh") print("3. 直接运行:./cloud-drive-server") if __name__ == '__main__': main()