feat: Add embedded backend packaging for all-in-one deployment

- Add backend/run_server.py entry point for embedded deployment
- Add backend/build.py PyInstaller script for backend packaging
- Modify config.py to support frozen executable paths
- Extend client/config.json with backend configuration section
- Add backend sidecar management in Electron main process
- Add Whisper model download progress reporting
- Update build-client.bat with --embedded-backend flag
- Update DEPLOYMENT.md with all-in-one deployment documentation

This enables packaging frontend and backend into a single executable
for simplified enterprise deployment. Backward compatible with
existing separate deployment mode (backend.embedded: false).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
egg
2025-12-17 10:06:29 +08:00
parent b1633fdcff
commit 58f379bc0c
11 changed files with 1003 additions and 17 deletions

View File

@@ -18,10 +18,13 @@ set "SCRIPT_DIR=%~dp0"
set "PROJECT_DIR=%SCRIPT_DIR%.."
set "CLIENT_DIR=%PROJECT_DIR%\client"
set "SIDECAR_DIR=%PROJECT_DIR%\sidecar"
set "BACKEND_DIR=%PROJECT_DIR%\backend"
set "BUILD_DIR=%PROJECT_DIR%\build"
REM 預設配置
set "SKIP_SIDECAR=false"
set "SKIP_BACKEND=true"
set "EMBEDDED_BACKEND=false"
set "CLEAN_BUILD=false"
set "API_URL="
@@ -35,6 +38,8 @@ if /i "%~1"=="electron" (set "COMMAND=electron" & shift & goto :parse_args)
if /i "%~1"=="clean" (set "COMMAND=clean" & shift & goto :parse_args)
if /i "%~1"=="help" (set "COMMAND=help" & shift & goto :parse_args)
if /i "%~1"=="--skip-sidecar" (set "SKIP_SIDECAR=true" & shift & goto :parse_args)
if /i "%~1"=="--skip-backend" (set "SKIP_BACKEND=true" & shift & goto :parse_args)
if /i "%~1"=="--embedded-backend" (set "EMBEDDED_BACKEND=true" & set "SKIP_BACKEND=false" & shift & goto :parse_args)
if /i "%~1"=="--clean" (set "CLEAN_BUILD=true" & shift & goto :parse_args)
if /i "%~1"=="--api-url" (set "API_URL=%~2" & shift & shift & goto :parse_args)
echo %RED%[ERROR]%NC% 未知參數: %~1
@@ -126,6 +131,10 @@ if exist "%SIDECAR_DIR%\dist" rmdir /s /q "%SIDECAR_DIR%\dist"
if exist "%SIDECAR_DIR%\build" rmdir /s /q "%SIDECAR_DIR%\build"
if exist "%SIDECAR_DIR%\venv" rmdir /s /q "%SIDECAR_DIR%\venv"
if exist "%SIDECAR_DIR%\*.spec" del /q "%SIDECAR_DIR%\*.spec"
if exist "%BACKEND_DIR%\dist" rmdir /s /q "%BACKEND_DIR%\dist"
if exist "%BACKEND_DIR%\build" rmdir /s /q "%BACKEND_DIR%\build"
if exist "%BACKEND_DIR%\venv" rmdir /s /q "%BACKEND_DIR%\venv"
if exist "%BACKEND_DIR%\*.spec" del /q "%BACKEND_DIR%\*.spec"
echo %GREEN%[OK]%NC% 建置目錄已清理
goto :eof
@@ -194,6 +203,127 @@ if exist "dist\transcriber" (
)
goto :eof
:setup_backend_venv
echo %BLUE%[STEP]%NC% 設置 Backend 建置環境...
cd /d "%BACKEND_DIR%"
if not exist "venv" (
echo %BLUE%[INFO]%NC% 創建虛擬環境...
%PYTHON_CMD% -m venv venv
)
echo %BLUE%[INFO]%NC% 安裝 Backend 依賴...
call venv\Scripts\activate.bat
python -m pip install --upgrade pip -q
python -m pip install -r requirements.txt -q
echo %BLUE%[INFO]%NC% 安裝 PyInstaller...
python -m pip install pyinstaller -q
echo %GREEN%[OK]%NC% Backend 建置環境就緒
goto :eof
:build_backend
echo %BLUE%[STEP]%NC% 打包 Backend (Python → 獨立執行檔)...
cd /d "%BACKEND_DIR%"
call venv\Scripts\activate.bat
if not exist "dist" mkdir dist
echo %BLUE%[INFO]%NC% 執行 PyInstaller...
echo %BLUE%[INFO]%NC% 這可能需要幾分鐘...
pyinstaller ^
--onedir ^
--name backend ^
--distpath dist ^
--workpath build ^
--specpath . ^
--noconfirm ^
--clean ^
--log-level WARN ^
--console ^
--hidden-import=uvicorn ^
--hidden-import=uvicorn.logging ^
--hidden-import=uvicorn.loops ^
--hidden-import=uvicorn.loops.auto ^
--hidden-import=uvicorn.protocols ^
--hidden-import=uvicorn.protocols.http ^
--hidden-import=uvicorn.protocols.http.auto ^
--hidden-import=uvicorn.protocols.websockets ^
--hidden-import=uvicorn.protocols.websockets.auto ^
--hidden-import=uvicorn.lifespan ^
--hidden-import=uvicorn.lifespan.on ^
--hidden-import=uvicorn.lifespan.off ^
--hidden-import=fastapi ^
--hidden-import=starlette ^
--hidden-import=pydantic ^
--hidden-import=pydantic_core ^
--hidden-import=mysql.connector ^
--hidden-import=mysql.connector.pooling ^
--hidden-import=httpx ^
--hidden-import=httpcore ^
--hidden-import=jose ^
--hidden-import=jose.jwt ^
--hidden-import=cryptography ^
--hidden-import=openpyxl ^
--hidden-import=multipart ^
--hidden-import=python_multipart ^
--hidden-import=dotenv ^
--hidden-import=app ^
--hidden-import=app.main ^
--hidden-import=app.config ^
--hidden-import=app.database ^
--hidden-import=app.auth ^
--hidden-import=app.routers ^
--hidden-import=app.routers.auth ^
--hidden-import=app.routers.meetings ^
--hidden-import=app.routers.dify ^
--hidden-import=app.routers.health ^
--hidden-import=app.routers.excel ^
--collect-data=pydantic ^
--collect-data=uvicorn ^
run_server.py
if exist "dist\backend" (
echo %BLUE%[INFO]%NC% 複製 template 目錄...
if exist "template" (
xcopy /s /e /y "template\*" "dist\backend\template\" >nul 2>&1
)
if not exist "dist\backend\record" mkdir "dist\backend\record"
echo %GREEN%[OK]%NC% Backend 打包完成: %BACKEND_DIR%\dist\backend
) else (
echo %RED%[ERROR]%NC% Backend 打包失敗
exit /b 1
)
goto :eof
:update_config_embedded
REM 更新 config.json 以啟用 embedded backend
if "%EMBEDDED_BACKEND%"=="false" goto :eof
echo %BLUE%[STEP]%NC% 啟用內嵌後端模式...
set "CONFIG_FILE=%CLIENT_DIR%\config.json"
if not exist "%CONFIG_FILE%" (
echo %YELLOW%[WARN]%NC% 找不到 config.json跳過內嵌模式設定
goto :eof
)
REM 使用 PowerShell 更新 backend.embedded = true
powershell -Command "$config = Get-Content '%CONFIG_FILE%' -Raw | ConvertFrom-Json; if (-not $config.backend) { $config | Add-Member -NotePropertyName 'backend' -NotePropertyValue @{} }; $config.backend.embedded = $true; $config | ConvertTo-Json -Depth 10 | Set-Content '%CONFIG_FILE%' -Encoding UTF8"
if errorlevel 1 (
echo %RED%[ERROR]%NC% 更新 config.json embedded 設定失敗
exit /b 1
)
echo %GREEN%[OK]%NC% 已啟用內嵌後端模式
goto :eof
:setup_client
echo %BLUE%[STEP]%NC% 設置前端建置環境...
@@ -303,11 +433,19 @@ if "%CLEAN_BUILD%"=="true" call :do_clean
REM 更新 API URL如果有指定
call :update_config
REM 更新 embedded backend 設定(如果有指定)
call :update_config_embedded
if "%SKIP_SIDECAR%"=="false" (
call :setup_sidecar_venv
call :build_sidecar
)
if "%SKIP_BACKEND%"=="false" (
call :setup_backend_venv
call :build_backend
)
call :setup_client
call :build_electron
call :finalize_build
@@ -364,19 +502,26 @@ echo clean 清理建置目錄
echo help 顯示此幫助訊息
echo.
echo 選項:
echo --api-url URL 後端 API URL (預設: http://localhost:8000/api)
echo --skip-sidecar 跳過 Sidecar 打包
echo --clean 建置前先清理
echo --api-url URL 後端 API URL (預設: http://localhost:8000/api)
echo --skip-sidecar 跳過 Sidecar 打包
echo --skip-backend 跳過 Backend 打包 (預設)
echo --embedded-backend 打包內嵌後端 (全包部署模式)
echo --clean 建置前先清理
echo.
echo 範例:
echo %~nx0 build 完整建置 (使用預設 localhost)
echo %~nx0 build --api-url "http://192.168.1.100:8000/api" 指定後端 URL
echo %~nx0 build --api-url "https://api.company.com/api" 使用公司伺服器
echo %~nx0 sidecar 僅打包 Sidecar
echo %~nx0 electron --skip-sidecar 僅打包 Electron
echo %~nx0 build 完整建置 (前端+Sidecar)
echo %~nx0 build --embedded-backend 全包部署 (含內嵌後端)
echo %~nx0 build --api-url "http://192.168.1.100:8000/api" 指定遠端後端
echo %~nx0 sidecar 僅打包 Sidecar
echo %~nx0 electron --skip-sidecar 僅打包 Electron
echo.
echo 部署模式:
echo 分離部署(預設): 前端連接遠端後端,使用 --api-url 指定後端地址
echo 全包部署: 使用 --embedded-backend 將後端打包進 exe雙擊即可運行
echo.
echo 注意:
echo - 首次打包 Sidecar 需下載 Whisper 模型,可能需要較長時間
echo - 全包部署需要額外約 50MB 空間用於後端
echo - 確保有足夠的磁碟空間 (建議 5GB+)
echo.
goto :eof