#!/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()}") 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}") # 创建部署目录结构 (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`: 启动脚本 - `.env.example`: 环境配置示例文件 ## 快速开始 1. **配置环境变量** ```bash cp .env.example .env # 编辑 .env 文件,配置数据库和Redis连接信息 nano .env ``` 2. **启动服务** ```bash chmod +x start.sh ./start.sh ``` 或者直接运行: ```bash ./cloud-drive-server ``` 3. **访问服务** - API文档: http://localhost:8000/docs - 健康检查: http://localhost:8000/api/v1/health ## 环境配置 主要配置项(.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 ``` ## 系统要求 - Linux 64位系统 - MySQL 5.7+ 或 8.0+ - Redis (可选) - 至少512MB内存 - 至少100MB磁盘空间 ## 日志 日志文件位置:`logs/app.log` ## 问题排查 1. **端口占用** - 默认端口8000,如需修改请编辑.env文件 2. **数据库连接失败** - 检查DATABASE_URL配置 - 确保数据库服务正在运行 - 检查防火墙设置 3. **权限问题** - 确保程序有执行权限:`chmod +x cloud-drive-server` - 确保有写入logs和uploads目录的权限 ## 后台运行 使用systemd或supervisor管理服务进程: ### systemd 配置示例 创建服务文件 `/etc/systemd/system/cloud-drive.service`: ```ini [Unit] Description=Cloud Drive Backend Service After=network.target [Service] Type=simple User=www-data WorkingDirectory=/path/to/deploy/directory ExecStart=/path/to/deploy/directory/cloud-drive-server Restart=always RestartSec=10 [Install] WantedBy=multi-user.target ``` 启用和启动服务: ```bash sudo systemctl daemon-reload sudo systemctl enable cloud-drive sudo systemctl start cloud-drive ``` ''' 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 了解部署说明") if __name__ == '__main__': main()