mirror of
https://github.com/rnvm9wjdtj-bot/myaps_api.git
synced 2026-06-02 05:54:40 +00:00
召回ubuntu部署脚本
This commit is contained in:
+100
-12
@@ -20,7 +20,7 @@
|
||||
- 按照界面提示进行操作
|
||||
|
||||
#### 2.1.2 主要功能
|
||||
- **1. 安装服务**:自动检查环境、安装依赖、配置服务
|
||||
- **1. 安装服务**:自动检查环境、安装依赖、配置服务(在线模式)
|
||||
- **2. 启动服务**:启动已安装的服务
|
||||
- **3. 停止服务**:停止正在运行的服务
|
||||
- **4. 重启服务**:重启服务
|
||||
@@ -31,6 +31,80 @@
|
||||
- **9. 查看帮助**:显示使用说明
|
||||
- **A. 健康检查**:执行 HTTP 健康检查,验证服务响应
|
||||
- **B. 滚动更新**:优雅重启,最小化更新过程中的停机时间
|
||||
- **C. 离线安装**:使用本地离线包进行安装,无需网络连接
|
||||
|
||||
### 2.3 离线部署方式(无外网环境)
|
||||
|
||||
当部署环境没有外网连接时,可以使用离线部署方式。项目已预先准备了完整的离线依赖包。
|
||||
|
||||
#### 2.3.1 离线包结构
|
||||
```
|
||||
offline_packages/
|
||||
└── windows/
|
||||
├── python-3.12.2.exe # Python 安装包(可选)
|
||||
├── Redis-x64-5.0.14.1.msi # Redis 安装包(可选)
|
||||
├── install_dependencies.bat # 离线依赖安装脚本
|
||||
├── *.whl # 所有 Python 依赖包
|
||||
└── requirements.txt # 依赖清单
|
||||
```
|
||||
|
||||
#### 2.3.2 部署步骤
|
||||
|
||||
**方法一:使用傻瓜式部署工具(推荐)**
|
||||
|
||||
1. **准备安装包**:
|
||||
- 将整个项目目录复制到目标服务器
|
||||
- 确保 `offline_packages/windows/` 目录完整
|
||||
|
||||
2. **运行部署工具**:
|
||||
- 右键点击 `simple_deploy.bat`
|
||||
- 选择 "以管理员身份运行"
|
||||
- 选择选项 **C. Install service (offline mode)**
|
||||
|
||||
3. **等待安装完成**:
|
||||
- 脚本会自动创建虚拟环境
|
||||
- 使用本地离线包安装所有依赖
|
||||
- 配置 Windows 服务
|
||||
|
||||
**方法二:手动离线安装**
|
||||
|
||||
1. **安装 Python(如果未安装)**:
|
||||
```bash
|
||||
# 使用离线安装包安装 Python
|
||||
offline_packages\windows\python-3.12.2.exe /quiet InstallAllUsers=1 PrependPath=1
|
||||
```
|
||||
|
||||
2. **运行离线安装脚本**:
|
||||
```bash
|
||||
# 进入离线包目录
|
||||
cd d:\code\myaps_fastapi\offline_packages\windows
|
||||
|
||||
# 运行离线安装脚本
|
||||
install_dependencies.bat
|
||||
```
|
||||
|
||||
3. **配置服务**:
|
||||
```bash
|
||||
# 使用部署工具配置服务
|
||||
scripts\deploy\simple_deploy.bat
|
||||
# 选择选项 1 安装服务(此时依赖已安装)
|
||||
```
|
||||
|
||||
#### 2.3.3 离线包说明
|
||||
|
||||
| 文件类型 | 说明 |
|
||||
|---------|------|
|
||||
| `.whl` 文件 | Python Wheel 格式的预编译依赖包 |
|
||||
| `python-*.exe` | Python 官方安装程序 |
|
||||
| `install_dependencies.bat` | 一键离线安装脚本 |
|
||||
| `requirements.txt` | 依赖版本清单 |
|
||||
|
||||
#### 2.3.4 注意事项
|
||||
|
||||
- **Python 版本要求**:离线包基于 Python 3.12 编译,建议使用相同版本
|
||||
- **包完整性**:确保 `offline_packages/windows/` 目录包含所有 `.whl` 文件
|
||||
- **权限要求**:所有操作需要管理员权限
|
||||
- **更新离线包**:如需更新依赖,需要在有网环境下使用 `pip download` 下载新包
|
||||
|
||||
### 2.2 传统部署方式
|
||||
|
||||
@@ -165,7 +239,20 @@ Get-Content d:\code\myaps_fastapi\logs\service_daemon.log -Tail 20
|
||||
4. 运行 `start_all.bat` 脚本
|
||||
5. 访问 `http://localhost` 验证部署
|
||||
|
||||
### 4.3 升级部署
|
||||
### 4.3 离线部署流程(无外网环境)
|
||||
1. **准备安装包**:将整个项目目录复制到目标服务器
|
||||
2. **运行部署工具**:
|
||||
- 右键点击 `scripts/deploy/simple_deploy.bat`
|
||||
- 选择 "以管理员身份运行"
|
||||
- 选择选项 **C. Install service (offline mode)**
|
||||
3. **等待安装完成**:
|
||||
- 脚本自动创建虚拟环境
|
||||
- 使用本地离线包安装所有依赖
|
||||
- 配置 Windows 服务
|
||||
4. **启动服务**:选择选项 2 "启动服务"
|
||||
5. **验证部署**:选择选项 A "健康检查" 或访问 `http://localhost:8000`
|
||||
|
||||
### 4.4 升级部署
|
||||
1. 运行 `simple_deploy.bat`
|
||||
2. 选择选项 3 "停止服务"(或选项 B "滚动更新")
|
||||
3. 更新代码
|
||||
@@ -217,16 +304,17 @@ Get-Content d:\code\myaps_fastapi\logs\service_daemon.log -Tail 20
|
||||
|
||||
## 8. 部署方式对比
|
||||
|
||||
| 特性 | 傻瓜式部署 | 传统部署 |
|
||||
|------|-----------|----------|
|
||||
| 操作难度 | 低(图形界面) | 中(命令行) |
|
||||
| 自动化程度 | 高(自动检查和安装) | 中(需要手动操作) |
|
||||
| 多进程支持 | ✅ 内置支持 | ✅ 需要手动配置 |
|
||||
| 服务管理 | ✅ 完整的服务生命周期管理 | ⚠️ 基本的启动停止 |
|
||||
| 环境检查 | ✅ 自动检查 | ❌ 需要手动检查 |
|
||||
| 健康检查 | ✅ 内置 HTTP 检查 | ❌ 无 |
|
||||
| 滚动更新 | ✅ 优雅重启支持 | ❌ 无 |
|
||||
| 适合人群 | 无IT基础用户 | 有一定技术基础用户 |
|
||||
| 特性 | 傻瓜式部署(在线) | 傻瓜式部署(离线) | 传统部署 |
|
||||
|------|-------------------|-------------------|----------|
|
||||
| 操作难度 | 低(图形界面) | 低(图形界面) | 中(命令行) |
|
||||
| 自动化程度 | 高(自动检查和安装) | 高(自动检查和安装) | 中(需要手动操作) |
|
||||
| 网络需求 | ✅ 需要外网 | ❌ 无需网络 | ❌ 无需网络 |
|
||||
| 多进程支持 | ✅ 内置支持 | ✅ 内置支持 | ✅ 需要手动配置 |
|
||||
| 服务管理 | ✅ 完整的服务生命周期管理 | ✅ 完整的服务生命周期管理 | ⚠️ 基本的启动停止 |
|
||||
| 环境检查 | ✅ 自动检查 | ✅ 自动检查 | ❌ 需要手动检查 |
|
||||
| 健康检查 | ✅ 内置 HTTP 检查 | ✅ 内置 HTTP 检查 | ❌ 无 |
|
||||
| 滚动更新 | ✅ 优雅重启支持 | ✅ 优雅重启支持 | ❌ 无 |
|
||||
| 适合人群 | 无IT基础用户 | 无IT基础用户(离线环境) | 有一定技术基础用户 |
|
||||
|
||||
## 9. 系统要求
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ echo 8. Clean log files
|
||||
echo 9. View help
|
||||
echo A. Health check (HTTP endpoint)
|
||||
echo B. Rolling update (graceful restart)
|
||||
echo C. Install service (offline mode)
|
||||
echo 0. Exit
|
||||
echo.
|
||||
echo ============================================================
|
||||
@@ -102,6 +103,7 @@ if "%choice%"=="8" goto :CLEAN_LOGS
|
||||
if "%choice%"=="9" goto :HELP
|
||||
if /i "%choice%"=="A" goto :HEALTH_CHECK
|
||||
if /i "%choice%"=="B" goto :ROLLING_UPDATE
|
||||
if /i "%choice%"=="C" goto :INSTALL_OFFLINE
|
||||
if "%choice%"=="0" goto :EXIT
|
||||
|
||||
echo Invalid choice: [%choice%]
|
||||
@@ -297,7 +299,7 @@ echo Help information
|
||||
echo ============================================================
|
||||
echo.
|
||||
|
||||
echo 1. Install service: Install service as Windows system service
|
||||
echo 1. Install service: Install service as Windows system service (online)
|
||||
echo 2. Start service: Start the installed service
|
||||
echo 3. Stop service: Stop the running service
|
||||
echo 4. Restart service: Restart the service
|
||||
@@ -308,6 +310,7 @@ echo 8. Clean logs: Clean old log files
|
||||
echo 9. View help: Display this help
|
||||
echo A. Health check: Perform HTTP health check
|
||||
echo B. Rolling update: Graceful restart for updates
|
||||
echo C. Install offline: Install service using local packages (no internet)
|
||||
echo 0. Exit: Exit the tool
|
||||
echo.
|
||||
pause
|
||||
@@ -392,6 +395,108 @@ echo.
|
||||
pause
|
||||
goto :MENU
|
||||
|
||||
:INSTALL_OFFLINE
|
||||
cls
|
||||
echo ============================================================
|
||||
echo Install service (offline mode)
|
||||
echo ============================================================
|
||||
echo.
|
||||
echo Note: This mode uses local packages for offline deployment.
|
||||
echo Ensure offline packages exist in: offline_packages\windows
|
||||
echo.
|
||||
|
||||
%PYTHON_EXE% --version >nul 2>&1
|
||||
if %errorLevel% neq 0 (
|
||||
echo Error: Python not found!
|
||||
pause
|
||||
goto :MENU
|
||||
)
|
||||
|
||||
set "OFFLINE_PACKAGES_DIR=%PROJECT_ROOT%\offline_packages\windows"
|
||||
if not exist "%OFFLINE_PACKAGES_DIR%" (
|
||||
echo Error: Offline packages directory not found!
|
||||
echo Expected: %OFFLINE_PACKAGES_DIR%
|
||||
pause
|
||||
goto :MENU
|
||||
)
|
||||
|
||||
if not exist "%PROJECT_ROOT%\requirements.txt" (
|
||||
echo Error: requirements.txt not found!
|
||||
pause
|
||||
goto :MENU
|
||||
)
|
||||
|
||||
echo [1/4] Creating virtual environment...
|
||||
if exist "%VENV_DIR%" (
|
||||
echo Removing existing virtual environment...
|
||||
rmdir /s /q "%VENV_DIR%"
|
||||
)
|
||||
%PYTHON_EXE% -m venv "%VENV_DIR%"
|
||||
if %errorLevel% neq 0 (
|
||||
echo Error: Failed to create virtual environment!
|
||||
pause
|
||||
goto :MENU
|
||||
)
|
||||
echo Virtual environment created successfully
|
||||
|
||||
echo.
|
||||
echo [2/4] Installing dependencies from local packages...
|
||||
echo This may take a few minutes...
|
||||
"%VENV_DIR%\Scripts\pip.exe" install --no-index --find-links="%OFFLINE_PACKAGES_DIR%" -r "%PROJECT_ROOT%\requirements.txt"
|
||||
if %errorLevel% neq 0 (
|
||||
echo Error: Failed to install dependencies!
|
||||
echo Please check if all required packages exist in offline_packages\windows
|
||||
pause
|
||||
goto :MENU
|
||||
)
|
||||
echo Dependencies installed successfully
|
||||
|
||||
echo.
|
||||
echo [3/4] Installing Gunicorn and Uvicorn...
|
||||
"%VENV_DIR%\Scripts\pip.exe" install --no-index --find-links="%OFFLINE_PACKAGES_DIR%" gunicorn uvicorn[standard]
|
||||
if %errorLevel% neq 0 (
|
||||
echo Warning: Failed to install Gunicorn/Uvicorn from offline packages!
|
||||
echo Trying online installation...
|
||||
"%VENV_DIR%\Scripts\pip.exe" install gunicorn uvicorn[standard]
|
||||
if %errorLevel% neq 0 (
|
||||
echo Error: Failed to install Gunicorn/Uvicorn!
|
||||
pause
|
||||
goto :MENU
|
||||
)
|
||||
)
|
||||
echo Gunicorn and Uvicorn installed successfully
|
||||
|
||||
if not exist "%PROJECT_ROOT%\logs" (
|
||||
mkdir "%PROJECT_ROOT%\logs"
|
||||
)
|
||||
|
||||
echo.
|
||||
echo [4/4] Configuring Windows service...
|
||||
set "RUN_PS1=%SCRIPT_DIR%..\run.ps1"
|
||||
|
||||
"%NSSM_EXE%" install "%SERVICE_NAME%" powershell.exe
|
||||
"%NSSM_EXE%" set "%SERVICE_NAME%" AppParameters "-ExecutionPolicy Bypass -NoProfile -File %RUN_PS1% -Mode service"
|
||||
"%NSSM_EXE%" set "%SERVICE_NAME%" AppDirectory "%PROJECT_ROOT%"
|
||||
"%NSSM_EXE%" set "%SERVICE_NAME%" Start SERVICE_AUTO_START
|
||||
"%NSSM_EXE%" set "%SERVICE_NAME%" AppStdout "%PROJECT_ROOT%\logs\nssm_stdout.log"
|
||||
"%NSSM_EXE%" set "%SERVICE_NAME%" AppStderr "%PROJECT_ROOT%\logs\nssm_stderr.log"
|
||||
"%NSSM_EXE%" set "%SERVICE_NAME%" AppRestartDelay 60000
|
||||
"%NSSM_EXE%" set "%SERVICE_NAME%" AppThrottle 300000
|
||||
"%NSSM_EXE%" set "%SERVICE_NAME%" AppExit Default Restart
|
||||
"%NSSM_EXE%" set "%SERVICE_NAME%" AppExit 1 Restart
|
||||
"%NSSM_EXE%" set "%SERVICE_NAME%" AppExit 0 Restart
|
||||
|
||||
echo.
|
||||
echo Service installed successfully in offline mode!
|
||||
echo Service name: %SERVICE_NAME%
|
||||
echo.
|
||||
echo Note: If you encounter dependency issues, please ensure:
|
||||
echo 1. All required .whl packages are in offline_packages\windows
|
||||
echo 2. Python version matches (Python 3.12 recommended)
|
||||
echo.
|
||||
pause
|
||||
goto :MENU
|
||||
|
||||
:EXIT
|
||||
cls
|
||||
echo ============================================================
|
||||
|
||||
@@ -0,0 +1,396 @@
|
||||
# MyAPS Ubuntu 部署指南(完全离线版)
|
||||
|
||||
## 📁 目录结构
|
||||
|
||||
```
|
||||
scripts/deploy_ubuntu/
|
||||
├── deploy.sh # 主部署脚本(完全离线)
|
||||
├── start.sh # 启动服务
|
||||
├── stop.sh # 停止服务
|
||||
├── restart.sh # 重启服务
|
||||
├── status.sh # 查看状态
|
||||
├── prepare_offline.sh # 打包离线依赖(开发机用)
|
||||
└── nginx.conf # Nginx 配置模板
|
||||
```
|
||||
|
||||
## 🚀 部署步骤
|
||||
|
||||
### 前提条件
|
||||
|
||||
目标服务器为 **完全无外网环境**,所有依赖已提前下载。
|
||||
|
||||
### 1. 在有外网的开发机准备离线包
|
||||
|
||||
```bash
|
||||
# 在开发机执行(需要外网)
|
||||
cd /path/to/myaps_fastapi
|
||||
|
||||
# 方式一:使用已下载的 Ubuntu 离线包
|
||||
# 确认 offline_packages/ubuntu/ 目录下有所有依赖
|
||||
|
||||
# 方式二:重新下载(需外网)
|
||||
./scripts/deploy_ubuntu/prepare_offline.sh
|
||||
```
|
||||
|
||||
### 2. 打包整个项目
|
||||
|
||||
推荐使用 PowerShell 脚本打包,确保排除目录生效:
|
||||
|
||||
```powershell
|
||||
# 在项目根目录运行
|
||||
cd D:\code\myaps_fastapi
|
||||
.\scripts\deploy_ubuntu\package_for_deploy.ps1
|
||||
```
|
||||
|
||||
**打包结果**:
|
||||
- 输出文件:`D:\code\myaps_fastapi_YYYYMMDD.tar.gz`(YYYYMMDD 为日期)
|
||||
- 自动排除以下目录:
|
||||
|
||||
| 目录 | 说明 |
|
||||
|------|------|
|
||||
| `venv` | Python 虚拟环境(服务器上重新创建) |
|
||||
| `offline_packages` | 离线依赖包(太大,需单独拷贝) |
|
||||
| `logs` | 日志目录(无需迁移) |
|
||||
| `test` | 测试代码(无需部署) |
|
||||
| `storage` | 本地存储(无需迁移) |
|
||||
| `backups` | 备份目录(无需迁移) |
|
||||
| `.git` | Git 仓库 |
|
||||
| `__pycache__` / `*.pyc` | Python 编译文件 |
|
||||
|
||||
### 手动打包命令(Git Bash)
|
||||
|
||||
如果需要手动打包,可使用以下命令:
|
||||
|
||||
```bash
|
||||
# 进入项目上级目录
|
||||
cd /d/code/
|
||||
|
||||
# 创建临时目录
|
||||
mkdir myaps_fastapi_temp
|
||||
|
||||
# 复制文件(排除目录)
|
||||
rsync -av --exclude='venv' --exclude='offline_packages' --exclude='logs' \
|
||||
--exclude='test' --exclude='storage' --exclude='backups' --exclude='.git' \
|
||||
--exclude='__pycache__' --exclude='*.pyc' myaps_fastapi/ myaps_fastapi_temp/
|
||||
|
||||
# 打包
|
||||
tar -czvf myaps_fastapi.tar.gz myaps_fastapi_temp/
|
||||
|
||||
# 清理临时目录
|
||||
rm -rf myaps_fastapi_temp
|
||||
```
|
||||
|
||||
### 单独打包离线依赖包
|
||||
|
||||
```bash
|
||||
# 打包项目代码(不含离线包)
|
||||
.\scripts\deploy_ubuntu\package_for_deploy.ps1
|
||||
|
||||
# 单独打包离线依赖包
|
||||
cd D:\code\
|
||||
tar -czvf offline_packages.tar.gz myaps_fastapi/offline_packages/
|
||||
```
|
||||
|
||||
### 3. 传输到离线服务器
|
||||
|
||||
```bash
|
||||
# 方法一:使用 U 盘/移动硬盘拷贝
|
||||
# 将 myaps_fastapi.tar.gz 拷贝到服务器
|
||||
|
||||
# 方法二:内网 SCP(如果有内网网络)
|
||||
scp myaps_fastapi.tar.gz root@your-server:/opt/
|
||||
```
|
||||
|
||||
### 4. 在离线服务器解压
|
||||
|
||||
```bash
|
||||
# 在目标服务器执行
|
||||
cd /opt
|
||||
tar -xzvf myaps_fastapi.tar.gz
|
||||
mv myaps_fastapi_temp myaps_api
|
||||
cd /opt/myaps_api
|
||||
```
|
||||
|
||||
### 5. 配置 .env
|
||||
|
||||
编辑 `/opt/myaps_api/.env`,确保以下参数正确:
|
||||
|
||||
```ini
|
||||
# 项目配置
|
||||
PROJECT_DIR=JYHDXS # 租户目录(CHANGDE/JYHDXS/HACYXS)
|
||||
PROJECT_JSON=dev # dev/prod
|
||||
|
||||
# 部署配置
|
||||
WORKERS=4 # 工作进程数(建议为 CPU 核数)
|
||||
GUNICORN_BIND=127.0.0.1:8000
|
||||
GUNICORN_TIMEOUT=30
|
||||
APP_USER=www-data
|
||||
APP_ROOT=/opt/myaps_api/myaps_api # 注意:项目实际目录结构为 /opt/myaps_api/myaps_api
|
||||
|
||||
# 数据库配置(根据实际环境修改)
|
||||
MYAPS_DB_HOST=127.0.0.1
|
||||
MYAPS_DB_PORT=3306
|
||||
MYAPS_DB_USER=username
|
||||
MYAPS_DB_PASSWORD=password
|
||||
MYAPS_DB_SET=database_name
|
||||
MYAPS_MAIN_DB=database_name
|
||||
|
||||
# Redis 配置
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
```
|
||||
|
||||
### 6. 安装系统依赖(离线方式)
|
||||
|
||||
#### 6.1 安装基础依赖
|
||||
|
||||
```bash
|
||||
# 如果服务器从未安装过以下依赖,需要提前准备 deb 包
|
||||
|
||||
# 安装 Python 3.12(必须)
|
||||
# 方法:在有外网的 Ubuntu 机器上下载 deb 包
|
||||
# apt download python3.12 python3.12-venv python3.12-dev
|
||||
# 然后拷贝到离线服务器安装
|
||||
|
||||
# 安装编译依赖(某些 Python 包需要)
|
||||
# apt download build-essential libssl-dev libffi-dev
|
||||
|
||||
# 安装 MySQL 客户端库
|
||||
# apt download libmysqlclient-dev
|
||||
|
||||
# 安装完成后执行
|
||||
apt install ./python3.12*.deb ./build-essential*.deb ./libssl-dev*.deb ./libffi-dev*.deb
|
||||
```
|
||||
|
||||
#### 6.2 安装 Redis 数据库(离线方式)
|
||||
|
||||
```bash
|
||||
# 方法一:使用 deb 包完整安装(推荐,最可靠)
|
||||
# 1. 在有外网的 Ubuntu 机器上下载 Redis 及其所有依赖
|
||||
mkdir -p /tmp/redis_packages
|
||||
cd /tmp/redis_packages
|
||||
|
||||
# 自动获取并下载所有依赖包(最完整的方式)
|
||||
apt download $(apt-cache depends redis-server redis-tools | grep -E "Depends|Recommends" | cut -d: -f2 | tr -d '<> ')
|
||||
|
||||
# 或者手动下载已知的关键依赖(备选方案)
|
||||
# apt download redis-server redis-tools libjemalloc2 libhiredis0.14 liblzf1
|
||||
|
||||
# 查看下载的文件
|
||||
ls -la *.deb
|
||||
|
||||
# 2. 将所有 deb 包拷贝到离线服务器
|
||||
# 使用 U 盘/移动硬盘或 scp 命令
|
||||
# 拷贝到离线服务器的 /opt/redis_packages/ 目录
|
||||
|
||||
# 3. 在离线服务器上安装
|
||||
cd /opt/redis_packages
|
||||
# 方法 A:使用 dpkg 安装所有包
|
||||
apt --fix-broken install -y
|
||||
|
||||
# 方法 B:如果有部分依赖问题,使用 apt 本地安装(推荐)
|
||||
# apt install ./*.deb
|
||||
|
||||
# 方法二:源码编译安装(适用于无 deb 包的情况)
|
||||
# 1. 下载 Redis 源码(在有外网的机器上)
|
||||
# wget https://download.redis.io/releases/redis-7.4.0.tar.gz
|
||||
|
||||
# 2. 拷贝到离线服务器并解压
|
||||
# tar -xzvf redis-7.4.0.tar.gz
|
||||
# cd redis-7.4.0
|
||||
|
||||
# 3. 编译安装(需要先安装 build-essential)
|
||||
# apt install ./build-essential*.deb
|
||||
# make
|
||||
# make install
|
||||
|
||||
# 4. 创建配置文件和服务
|
||||
# mkdir -p /etc/redis /var/lib/redis
|
||||
# cp redis.conf /etc/redis/
|
||||
# useradd -r -s /bin/false redis
|
||||
# chown redis:redis /var/lib/redis
|
||||
|
||||
# 5. 创建 systemd 服务文件
|
||||
# cat > /etc/systemd/system/redis.service << 'EOF'
|
||||
# [Unit]
|
||||
# Description=Redis In-Memory Data Store
|
||||
# After=network.target
|
||||
|
||||
# [Service]
|
||||
# User=redis
|
||||
# Group=redis
|
||||
# ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
|
||||
# ExecStop=/usr/local/bin/redis-cli shutdown
|
||||
# Restart=always
|
||||
|
||||
# [Install]
|
||||
# WantedBy=multi-user.target
|
||||
# EOF
|
||||
|
||||
# 启动 Redis 服务(两种方法都需要)
|
||||
systemctl daemon-reload
|
||||
systemctl start redis-server
|
||||
systemctl enable redis-server
|
||||
|
||||
# 验证安装
|
||||
redis-cli ping
|
||||
# 输出: PONG
|
||||
```
|
||||
|
||||
#### 常见问题与解决
|
||||
|
||||
**问题:安装时提示缺少依赖包**
|
||||
|
||||
解决方法:确保使用了上面的方法一,使用 `apt-cache depends` 自动获取所有依赖。
|
||||
|
||||
**问题:dpkg 安装后仍有未配置的包**
|
||||
|
||||
解决方法:
|
||||
```bash
|
||||
# 强制修复配置
|
||||
apt-get -f install
|
||||
# 或者再次执行 dpkg 配置
|
||||
dpkg --configure -a
|
||||
```
|
||||
|
||||
**问题:如何检查已下载的依赖是否完整**
|
||||
|
||||
```bash
|
||||
# 在有外网的机器上模拟安装,检查是否还有缺失
|
||||
mkdir -p /tmp/test_install
|
||||
cd /tmp/test_install
|
||||
cp /tmp/redis_packages/*.deb .
|
||||
# 使用 apt 模拟安装(不会真正安装)
|
||||
apt install --dry-run ./*.deb
|
||||
```
|
||||
|
||||
### 7. 执行离线部署
|
||||
|
||||
```bash
|
||||
cd /opt/myaps_api
|
||||
chmod +x ./scripts/deploy_ubuntu/*.sh
|
||||
|
||||
# 首次部署(包含数据库迁移)
|
||||
./scripts/deploy_ubuntu/deploy.sh -d
|
||||
|
||||
# 增量更新(跳过数据库迁移,避免破坏数据)
|
||||
./scripts/deploy_ubuntu/deploy.sh -d -s
|
||||
```
|
||||
|
||||
**部署选项说明:**
|
||||
|
||||
| 选项 | 说明 |
|
||||
|------|------|
|
||||
| `-d` | 执行部署 |
|
||||
| `-s` | 跳过数据库迁移(用于增量更新) |
|
||||
| `-t <租户>` | 指定租户(如 CHANGDE、JYHDXS、HACYXS) |
|
||||
|
||||
**示例:**
|
||||
```bash
|
||||
# 首次部署,指定租户
|
||||
./scripts/deploy_ubuntu/deploy.sh -d -t CHANGDE
|
||||
|
||||
# 增量更新,跳过迁移
|
||||
./scripts/deploy_ubuntu/deploy.sh -d -s
|
||||
|
||||
# 指定租户且跳过迁移
|
||||
./scripts/deploy_ubuntu/deploy.sh -d -t CHANGDE -s
|
||||
```
|
||||
|
||||
### 8. 配置 Nginx(可选)
|
||||
|
||||
```bash
|
||||
# 安装 Nginx(提前准备 deb 包)
|
||||
# apt download nginx
|
||||
# dpkg -i nginx*.deb
|
||||
|
||||
# 复制配置
|
||||
cp ./scripts/deploy_ubuntu/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
# 测试配置
|
||||
nginx -t
|
||||
|
||||
# 重启 Nginx
|
||||
systemctl restart nginx
|
||||
systemctl enable nginx
|
||||
```
|
||||
|
||||
## 📝 常用命令
|
||||
|
||||
```bash
|
||||
# 启动服务
|
||||
./scripts/deploy_ubuntu/start.sh
|
||||
|
||||
# 停止服务
|
||||
./scripts/deploy_ubuntu/stop.sh
|
||||
|
||||
# 重启服务
|
||||
./scripts/deploy_ubuntu/restart.sh
|
||||
|
||||
# 查看状态
|
||||
./scripts/deploy_ubuntu/status.sh
|
||||
|
||||
# 查看日志
|
||||
journalctl -u MyAPS_API -f
|
||||
|
||||
# 切换租户(修改 .env 后重启)
|
||||
sed -i 's/PROJECT_DIR=JYHDXS/PROJECT_DIR=CHANGDE/' .env
|
||||
./scripts/deploy_ubuntu/restart.sh
|
||||
```
|
||||
|
||||
## 📦 离线依赖包说明
|
||||
|
||||
### 依赖包位置
|
||||
|
||||
```
|
||||
/opt/myaps_api/offline_packages/ubuntu/python_pkg/
|
||||
├── fastapi-0.136.1-py3-none-any.whl
|
||||
├── uvicorn-0.46.0-py3-none-any.whl
|
||||
├── gunicorn-26.0.0-py3-none-any.whl
|
||||
├── pandas-3.0.2-cp312-cp312-manylinux_*.whl
|
||||
├── numpy-2.4.4-cp312-cp312-manylinux_*.whl
|
||||
└── ... (共 56 个依赖包)
|
||||
```
|
||||
|
||||
### 离线包兼容性
|
||||
|
||||
| 类型 | 特征 | 说明 |
|
||||
|------|------|------|
|
||||
| `py3-none-any.whl` | 纯 Python 代码 | 跨平台通用 |
|
||||
| `manylinux_*.whl` | 编译后的二进制 | Ubuntu x86_64 专用 |
|
||||
|
||||
## ⚠️ 注意事项
|
||||
|
||||
1. **完全离线**:确保服务器无任何外网访问,所有依赖已提前准备
|
||||
2. **Python 版本**:必须使用 Python 3.12(依赖包为 cp312 版本)
|
||||
3. **权限问题**:建议使用 `www-data` 用户运行,而非 `root`
|
||||
4. **数据库连接**:确保 `.env` 中数据库配置正确且可达
|
||||
5. **防火墙**:确保端口 80/443/8000 已开放
|
||||
6. **系统依赖**:提前准备 `python3.12`, `build-essential`, `libssl-dev` 等 deb 包
|
||||
7. **APP_ROOT 配置**:确保 `APP_ROOT=/opt/myaps_api/myaps_api`(项目实际在二级目录)
|
||||
8. **只读文件系统**:如果 `/opt/myaps_api` 是只读挂载点,脚本会自动使用用户级别 Systemd 服务
|
||||
|
||||
## 🔧 故障排查
|
||||
|
||||
| 问题 | 解决方法 |
|
||||
|------|---------|
|
||||
| 服务启动失败 | `systemctl status MyAPS_API` |
|
||||
| 日志查看 | `journalctl -u MyAPS_API -f` |
|
||||
| 端口占用 | `lsof -i :8000` |
|
||||
| Nginx 配置错误 | `nginx -t` |
|
||||
| Python 版本不匹配 | 确认安装 Python 3.12 |
|
||||
| 依赖安装失败 | 检查 offline_packages/ubuntu/ 目录是否完整 |
|
||||
| 只读文件系统错误 | 检查 `/opt/myaps_api` 挂载状态,使用 `mount` 命令确认 |
|
||||
| Systemd 服务创建失败 | 脚本会自动回退到用户级别服务,使用 `systemctl --user` 命令 |
|
||||
|
||||
## 📋 部署检查清单
|
||||
|
||||
- [ ] 项目代码已拷贝到 `/opt/myaps_api/`
|
||||
- [ ] `.env` 配置文件已正确设置(`APP_ROOT=/opt/myaps_api/myaps_api`)
|
||||
- [ ] 离线依赖包存在于 `offline_packages/ubuntu/python_pkg/`
|
||||
- [ ] Python 3.12 已安装
|
||||
- [ ] 数据库服务已启动且可连接
|
||||
- [ ] Redis 服务已启动且可连接
|
||||
- [ ] 执行 `deploy.sh -d` 部署成功(首次部署)
|
||||
- [ ] 执行 `deploy.sh -d -s` 部署成功(增量更新)
|
||||
- [ ] 服务状态正常(`systemctl --user status MyAPS_API` 或 `systemctl status MyAPS_API`)
|
||||
@@ -0,0 +1,274 @@
|
||||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# MyAPS FastAPI Ubuntu 部署脚本
|
||||
# 自动从 .env 读取配置参数
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# 读取 .env 配置
|
||||
read_env() {
|
||||
# 获取脚本所在目录,用于定位项目根目录
|
||||
local SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||
local PROJECT_DIR_CANDIDATE=$(dirname "$SCRIPT_DIR") # scripts 目录的父目录
|
||||
|
||||
# 优先级:1. 当前目录 2. 脚本所在项目目录 3. APP_ROOT 环境变量
|
||||
local env_path=""
|
||||
|
||||
# 1. 检查当前目录
|
||||
if [ -f ".env" ]; then
|
||||
env_path=".env"
|
||||
# 2. 检查脚本所在项目目录
|
||||
elif [ -f "$PROJECT_DIR_CANDIDATE/.env" ]; then
|
||||
env_path="$PROJECT_DIR_CANDIDATE/.env"
|
||||
# 3. 使用 APP_ROOT 环境变量
|
||||
elif [ -n "$APP_ROOT" ] && [ -f "$APP_ROOT/.env" ]; then
|
||||
env_path="$APP_ROOT/.env"
|
||||
# 4. 默认路径
|
||||
elif [ -f "/opt/myaps_api/myaps_api/.env" ]; then
|
||||
env_path="/opt/myaps_api/myaps_api/.env"
|
||||
elif [ -f "/opt/myaps_api/.env" ]; then
|
||||
env_path="/opt/myaps_api/.env"
|
||||
fi
|
||||
|
||||
if [ -n "$env_path" ]; then
|
||||
echo " 读取环境变量: $env_path"
|
||||
|
||||
# 使用 source 命令读取环境变量(更可靠)
|
||||
# 创建临时文件,确保文件以换行符结尾
|
||||
local temp_file=$(mktemp)
|
||||
cat "$env_path" > "$temp_file"
|
||||
echo "" >> "$temp_file" # 添加换行符
|
||||
|
||||
# 使用 source 读取,但只导入大写字母开头的环境变量
|
||||
while IFS= read -r line; do
|
||||
if [[ ! "$line" =~ ^# && "$line" =~ ^[A-Z_]+= ]]; then
|
||||
export "$line"
|
||||
fi
|
||||
done < "$temp_file"
|
||||
|
||||
rm -f "$temp_file"
|
||||
|
||||
# 验证读取结果
|
||||
echo " 读取到 PROJECT_DIR: ${PROJECT_DIR:-未设置}"
|
||||
echo " 读取到 APP_ROOT: ${APP_ROOT:-未设置}"
|
||||
else
|
||||
echo "❌ 错误: .env 文件不存在"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 主部署函数
|
||||
deploy() {
|
||||
echo "========================================"
|
||||
echo " MyAPS Ubuntu 部署脚本"
|
||||
echo "========================================"
|
||||
|
||||
# 保存命令行传入的租户参数(如果有)
|
||||
local cmdline_project_dir="$PROJECT_DIR"
|
||||
|
||||
# 1. 读取环境变量
|
||||
echo "[1/6] 读取环境配置..."
|
||||
read_env
|
||||
|
||||
# 如果命令行指定了租户,覆盖 .env 中的配置
|
||||
if [ -n "$cmdline_project_dir" ]; then
|
||||
echo " 使用命令行指定的租户: $cmdline_project_dir"
|
||||
PROJECT_DIR="$cmdline_project_dir"
|
||||
fi
|
||||
|
||||
# 2. 验证必要参数
|
||||
echo "[2/6] 验证配置参数..."
|
||||
if [ -z "$PROJECT_DIR" ]; then
|
||||
echo "❌ 错误: PROJECT_DIR 未设置"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3. 创建目录结构
|
||||
echo "[3/6] 创建目录结构..."
|
||||
# 仅在目录不存在时创建(处理只读文件系统情况)
|
||||
if [ ! -d "${APP_ROOT:-/opt/myaps_api}/logs" ]; then
|
||||
mkdir -p "${APP_ROOT:-/opt/myaps_api}/logs" || echo " ⚠️ 无法创建 logs 目录(只读文件系统)"
|
||||
else
|
||||
echo " logs 目录已存在"
|
||||
fi
|
||||
|
||||
# 设置运行服务的用户
|
||||
if id "www-data" &>/dev/null; then
|
||||
APP_USER="www-data"
|
||||
echo " 使用 www-data 用户"
|
||||
else
|
||||
APP_USER="root"
|
||||
echo " www-data 用户不存在,使用 root 用户"
|
||||
fi
|
||||
|
||||
# 设置目录权限(跳过,只读文件系统)
|
||||
# chown -R ${APP_USER}:${APP_USER} "${APP_ROOT:-/opt/myaps_api}"
|
||||
echo " ⚠️ 跳过权限设置(只读文件系统)"
|
||||
|
||||
# 4. 安装依赖
|
||||
echo "[4/6] 安装 Python 依赖..."
|
||||
# 检查虚拟环境是否已存在
|
||||
if [ -d "${APP_ROOT:-/opt/myaps_api}/venv" ]; then
|
||||
echo " 虚拟环境已存在,跳过创建"
|
||||
else
|
||||
python3 -m venv "${APP_ROOT:-/opt/myaps_api}/venv"
|
||||
fi
|
||||
source "${APP_ROOT:-/opt/myaps_api}/venv/bin/activate"
|
||||
|
||||
if [ -d "offline_packages/ubuntu/python_pkg" ]; then
|
||||
echo " 使用 Ubuntu 离线依赖包..."
|
||||
# 先尝试完全离线安装
|
||||
if pip install --no-index --find-links=offline_packages/ubuntu/python_pkg -r requirements.txt 2>/dev/null; then
|
||||
echo " ✅ 完全离线安装成功"
|
||||
else
|
||||
echo " ⚠️ 部分包需要在线下载..."
|
||||
pip install --find-links=offline_packages/ubuntu/python_pkg -r requirements.txt
|
||||
fi
|
||||
elif [ -d "offline_packages" ]; then
|
||||
echo " 使用通用离线依赖包..."
|
||||
pip install --find-links=offline_packages -r requirements.txt
|
||||
else
|
||||
echo " 使用在线安装..."
|
||||
pip install -r requirements.txt
|
||||
fi
|
||||
|
||||
# 数据库迁移
|
||||
echo "[5/7] 执行数据库迁移..."
|
||||
if [ "$SKIP_MIGRATE" = true ]; then
|
||||
echo " ⏭️ 跳过数据库迁移(使用 -s 参数)"
|
||||
elif [ -f "scripts/migrate/auto_migrate.py" ]; then
|
||||
echo " 使用自动迁移脚本..."
|
||||
python scripts/migrate/auto_migrate.py
|
||||
elif command -v aerich &> /dev/null; then
|
||||
echo " 使用 Aerich 迁移..."
|
||||
aerich upgrade
|
||||
else
|
||||
echo " ⚠️ 未找到迁移脚本,请手动执行数据库迁移"
|
||||
fi
|
||||
|
||||
deactivate
|
||||
|
||||
# 6. 创建 Systemd 服务
|
||||
echo "[6/7] 创建 Systemd 服务..."
|
||||
|
||||
# 检测系统目录是否可写,否则使用用户级别服务
|
||||
if touch /etc/systemd/system/test_$$.service 2>/dev/null; then
|
||||
rm -f /etc/systemd/system/test_$$.service
|
||||
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME:-MyAPS_API}.service"
|
||||
SYSTEMCTL_CMD="systemctl"
|
||||
echo " 使用系统级别 Systemd 服务"
|
||||
else
|
||||
# 使用用户级别 Systemd 服务
|
||||
mkdir -p ~/.config/systemd/user/
|
||||
SERVICE_FILE="$HOME/.config/systemd/user/${SERVICE_NAME:-MyAPS_API}.service"
|
||||
SYSTEMCTL_CMD="systemctl --user"
|
||||
echo " 使用用户级别 Systemd 服务(系统只读)"
|
||||
fi
|
||||
|
||||
# 生成 Systemd 服务文件
|
||||
cat > "$SERVICE_FILE" << EOF
|
||||
[Unit]
|
||||
Description=MyAPS_API FastAPI Application
|
||||
After=network.target mysql.service redis.service
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
WorkingDirectory=${APP_ROOT:-/opt/myaps_api}
|
||||
# 使用 bash -c 方式启动,先加载 .env 文件再启动 Gunicorn
|
||||
ExecStart=/bin/bash -c "source ${APP_ROOT:-/opt/myaps_api}/.env && ${APP_ROOT:-/opt/myaps_api}/venv/bin/gunicorn --workers=4 --bind=127.0.0.1:8000 --timeout=30 --worker-class=uvicorn.workers.UvicornWorker --access-logfile=${APP_ROOT:-/opt/myaps_api}/logs/access.log --error-logfile=${APP_ROOT:-/opt/myaps_api}/logs/error.log main:app"
|
||||
ExecReload=/bin/kill -s HUP \$MAINPID
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF
|
||||
|
||||
# 7. 检查并启动 Redis 服务
|
||||
echo "[7/8] 检查 Redis 服务..."
|
||||
if systemctl is-active --quiet redis-server; then
|
||||
echo " ✅ Redis 已运行"
|
||||
else
|
||||
echo " 启动 Redis 服务..."
|
||||
systemctl daemon-reload
|
||||
systemctl enable redis-server
|
||||
systemctl start redis-server
|
||||
# 等待 Redis 启动
|
||||
sleep 2
|
||||
if redis-cli ping > /dev/null 2>&1; then
|
||||
echo " ✅ Redis 启动成功"
|
||||
else
|
||||
echo " ⚠️ Redis 启动失败,请手动检查"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 8. 启动应用服务
|
||||
echo "[8/8] 启动应用服务..."
|
||||
$SYSTEMCTL_CMD daemon-reload
|
||||
$SYSTEMCTL_CMD enable "${SERVICE_NAME:-MyAPS_API}"
|
||||
$SYSTEMCTL_CMD start "${SERVICE_NAME:-MyAPS_API}"
|
||||
|
||||
echo ""
|
||||
echo "✅ 部署完成!"
|
||||
echo " 租户: $PROJECT_DIR"
|
||||
echo " 服务名称: ${SERVICE_NAME:-MyAPS_API}"
|
||||
echo " 绑定地址: ${GUNICORN_BIND:-127.0.0.1:8000}"
|
||||
echo ""
|
||||
echo "查看状态: systemctl status ${SERVICE_NAME:-MyAPS_API}"
|
||||
echo "查看日志: journalctl -u ${SERVICE_NAME:-MyAPS_API} -f"
|
||||
echo ""
|
||||
echo "注意: 如果系统目录只读,将使用用户级别 Systemd 服务"
|
||||
echo " 使用 'systemctl --user status ${SERVICE_NAME:-MyAPS_API}' 查看状态"
|
||||
}
|
||||
|
||||
# 显示帮助
|
||||
usage() {
|
||||
echo "用法: $0 [选项]"
|
||||
echo ""
|
||||
echo "选项:"
|
||||
echo " -h, --help 显示帮助信息"
|
||||
echo " -d, --deploy 执行部署"
|
||||
echo " -t, --tenant 指定租户(可选,默认从 .env 读取)"
|
||||
echo " -s, --skip-migrate 跳过数据库迁移(适用于增量更新)"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 -d # 使用 .env 中的配置部署(含迁移)"
|
||||
echo " $0 -d -t CHANGDE # 指定租户部署"
|
||||
echo " $0 -d -s # 部署但跳过数据库迁移"
|
||||
echo " $0 -d -t CHANGDE -s # 指定租户部署,跳过迁移"
|
||||
}
|
||||
|
||||
# 解析参数
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-d|--deploy)
|
||||
DEPLOY=true
|
||||
shift
|
||||
;;
|
||||
-t|--tenant)
|
||||
PROJECT_DIR="$2"
|
||||
shift 2
|
||||
;;
|
||||
-s|--skip-migrate)
|
||||
SKIP_MIGRATE=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "未知选项: $1"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 执行部署
|
||||
if [ "$DEPLOY" = true ]; then
|
||||
deploy
|
||||
else
|
||||
usage
|
||||
fi
|
||||
@@ -0,0 +1,59 @@
|
||||
# ==============================================================================
|
||||
# MyAPS Nginx 配置模板
|
||||
# ==============================================================================
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
# MyAPS 应用配置
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
# 静态文件
|
||||
location /static/ {
|
||||
root /opt/myaps;
|
||||
expires 30d;
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
location /health {
|
||||
proxy_pass http://127.0.0.1:8000/health;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
# API 代理
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
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;
|
||||
|
||||
# WebSocket 支持
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# 错误页面
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
# MyAPS Project Packaging Script (PowerShell)
|
||||
# Excludes unnecessary directories and files
|
||||
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host " MyAPS Package Script" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
|
||||
if (-not (Test-Path "main.py")) {
|
||||
Write-Host "ERROR: Please run this script from project root directory" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
$projectDir = Get-Location
|
||||
$projectName = Split-Path $projectDir -Leaf
|
||||
$parentDir = Split-Path $projectDir -Parent
|
||||
$timestamp = Get-Date -Format "yyyyMMdd"
|
||||
$outputFile = Join-Path $parentDir "${projectName}_${timestamp}.tar.gz"
|
||||
$tempDir = Join-Path $parentDir "${projectName}_temp"
|
||||
|
||||
Write-Host "[1/4] Current project: $projectName" -ForegroundColor Green
|
||||
|
||||
# Remove existing temp directory
|
||||
if (Test-Path $tempDir) {
|
||||
Write-Host "[2/4] Cleaning up existing temp directory..." -ForegroundColor Green
|
||||
Remove-Item -Recurse -Force $tempDir
|
||||
}
|
||||
|
||||
Write-Host "[2/4] Copying project files (excluding unwanted items)..." -ForegroundColor Green
|
||||
|
||||
# Define items to exclude
|
||||
$excludeItems = @(
|
||||
"venv",
|
||||
"offline_packages",
|
||||
"logs",
|
||||
"test",
|
||||
"storage",
|
||||
"backups",
|
||||
".git",
|
||||
"__pycache__",
|
||||
".env" # 排除 .env 文件,让服务器使用自己的配置
|
||||
)
|
||||
|
||||
# Get all items in project directory
|
||||
$items = Get-ChildItem -Path $projectDir
|
||||
|
||||
foreach ($item in $items) {
|
||||
# Skip excluded items
|
||||
if ($excludeItems -contains $item.Name) {
|
||||
Write-Host " Skipping: $($item.Name)"
|
||||
continue
|
||||
}
|
||||
|
||||
# Copy the item
|
||||
$destPath = Join-Path $tempDir $item.Name
|
||||
Copy-Item -Path $item.FullName -Destination $destPath -Recurse -Force
|
||||
}
|
||||
|
||||
Write-Host "[3/4] Removing compiled files from subdirectories..." -ForegroundColor Green
|
||||
|
||||
# Remove .pyc files from all subdirectories
|
||||
Get-ChildItem -Path $tempDir -Recurse -Filter "*.pyc" | Remove-Item -Force
|
||||
Get-ChildItem -Path $tempDir -Recurse -Filter "*.pyo" | Remove-Item -Force
|
||||
Get-ChildItem -Path $tempDir -Recurse -Filter "__pycache__" -Directory | Remove-Item -Recurse -Force
|
||||
|
||||
Write-Host "[4/4] Packing..." -ForegroundColor Green
|
||||
|
||||
# Create tar.gz
|
||||
tar -czvf $outputFile -C $parentDir "${projectName}_temp"
|
||||
|
||||
# Clean up
|
||||
Remove-Item -Recurse -Force $tempDir
|
||||
|
||||
Write-Host "" -ForegroundColor Cyan
|
||||
Write-Host "SUCCESS: Package completed!" -ForegroundColor Green
|
||||
Write-Host "File: $outputFile" -ForegroundColor Green
|
||||
Write-Host "" -ForegroundColor Cyan
|
||||
Write-Host "Excluded items:" -ForegroundColor Yellow
|
||||
Write-Host "- venv (Virtual environment)"
|
||||
Write-Host "- offline_packages (Offline dependencies)"
|
||||
Write-Host "- logs (Log files)"
|
||||
Write-Host "- test (Test code)"
|
||||
Write-Host "- storage (Local storage)"
|
||||
Write-Host "- backups (Backup files)"
|
||||
Write-Host "- .git (Git repository)"
|
||||
Write-Host "- __pycache__ and *.pyc (Compiled files)"
|
||||
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# 打包离线依赖包(在有外网的开发机执行)
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
echo "========================================"
|
||||
echo " 准备离线依赖包"
|
||||
echo "========================================"
|
||||
|
||||
# 检查 requirements.txt 是否存在
|
||||
if [ ! -f "requirements.txt" ]; then
|
||||
echo "❌ 错误: requirements.txt 不存在"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建离线包目录
|
||||
echo "[1/2] 创建离线包目录..."
|
||||
mkdir -p offline_packages
|
||||
|
||||
# 下载依赖
|
||||
echo "[2/2] 下载 Python 依赖..."
|
||||
pip download -r requirements.txt -d offline_packages/
|
||||
|
||||
echo ""
|
||||
echo "✅ 离线依赖包准备完成!"
|
||||
echo " 目录: $(pwd)/offline_packages/"
|
||||
echo " 文件数: $(ls offline_packages/ | wc -l)"
|
||||
echo ""
|
||||
echo "使用方式:"
|
||||
echo " 1. 将整个项目目录拷贝到离线服务器"
|
||||
echo " 2. 运行 deploy.sh -d 进行部署"
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# 重启 MyAPS 服务
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# 读取 .env 配置
|
||||
read_env() {
|
||||
if [ -f ".env" ]; then
|
||||
while IFS= read -r line; do
|
||||
if [[ ! "$line" =~ ^# && "$line" =~ ^[A-Z_]+= ]]; then
|
||||
export "$line"
|
||||
fi
|
||||
done < ".env"
|
||||
fi
|
||||
}
|
||||
|
||||
read_env
|
||||
|
||||
echo "🔄 重启 ${SERVICE_NAME:-MyAPS_API} 服务..."
|
||||
systemctl restart "${SERVICE_NAME:-MyAPS_API}"
|
||||
echo "✅ 服务已重启"
|
||||
echo "查看状态: systemctl status ${SERVICE_NAME:-MyAPS_API}"
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# 启动 MyAPS 服务
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# 读取 .env 配置
|
||||
read_env() {
|
||||
if [ -f ".env" ]; then
|
||||
while IFS= read -r line; do
|
||||
if [[ ! "$line" =~ ^# && "$line" =~ ^[A-Z_]+= ]]; then
|
||||
export "$line"
|
||||
fi
|
||||
done < ".env"
|
||||
fi
|
||||
}
|
||||
|
||||
read_env
|
||||
|
||||
echo "🚀 启动 ${SERVICE_NAME:-MyAPS_API} 服务..."
|
||||
systemctl start "${SERVICE_NAME:-MyAPS_API}"
|
||||
echo "✅ 服务已启动"
|
||||
echo "查看状态: systemctl status ${SERVICE_NAME:-MyAPS_API}"
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# 查看 MyAPS 服务状态
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# 读取 .env 配置
|
||||
read_env() {
|
||||
if [ -f ".env" ]; then
|
||||
while IFS= read -r line; do
|
||||
if [[ ! "$line" =~ ^# && "$line" =~ ^[A-Z_]+= ]]; then
|
||||
export "$line"
|
||||
fi
|
||||
done < ".env"
|
||||
fi
|
||||
}
|
||||
|
||||
read_env
|
||||
|
||||
echo "📊 ${SERVICE_NAME:-MyAPS_API} 服务状态:"
|
||||
systemctl status "${SERVICE_NAME:-MyAPS_API}"
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# 停止 MyAPS 服务
|
||||
# ==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
# 读取 .env 配置
|
||||
read_env() {
|
||||
if [ -f ".env" ]; then
|
||||
while IFS= read -r line; do
|
||||
if [[ ! "$line" =~ ^# && "$line" =~ ^[A-Z_]+= ]]; then
|
||||
export "$line"
|
||||
fi
|
||||
done < ".env"
|
||||
fi
|
||||
}
|
||||
|
||||
read_env
|
||||
|
||||
echo "⏹️ 停止 ${SERVICE_NAME:-MyAPS_API} 服务..."
|
||||
systemctl stop "${SERVICE_NAME:-MyAPS_API}"
|
||||
echo "✅ 服务已停止"
|
||||
Reference in New Issue
Block a user