Files
Meeting_Assistant/scripts/deploy-backend.sh
egg 01aee1fd0d feat: Extract hardcoded configs to environment variables
- Add environment variable configuration for backend and frontend
- Backend: DB_POOL_SIZE, JWT_EXPIRE_HOURS, timeout configs, directory paths
- Frontend: VITE_API_BASE_URL, VITE_UPLOAD_TIMEOUT, Whisper configs
- Create deployment script (scripts/deploy-backend.sh)
- Create 1Panel deployment guide (docs/1panel-deployment.md)
- Update DEPLOYMENT.md with env var documentation
- Create README.md with project overview
- Remove obsolete PRD.md, SDD.md, TDD.md (replaced by OpenSpec)
- Keep CORS allow_origins=["*"] for Electron EXE distribution

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 14:31:55 +08:00

440 lines
11 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
#
# Meeting Assistant Backend - Deployment Script
# 用於在 1Panel 或其他 Linux 服務器上部署後端服務
#
set -e
# 顏色定義
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 預設配置
DEFAULT_INSTALL_DIR="/opt/meeting-assistant"
DEFAULT_USER="meeting"
DEFAULT_PORT="8000"
# 函數:印出訊息
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[OK]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 函數:顯示幫助
show_help() {
echo ""
echo "Meeting Assistant Backend 部署腳本"
echo ""
echo "用法: $0 [命令] [選項]"
echo ""
echo "命令:"
echo " install 安裝後端服務"
echo " update 更新後端服務"
echo " uninstall 移除後端服務"
echo " status 顯示服務狀態"
echo " logs 顯示服務日誌"
echo " help 顯示此幫助訊息"
echo ""
echo "選項:"
echo " --dir DIR 安裝目錄 (預設: $DEFAULT_INSTALL_DIR)"
echo " --user USER 運行服務的用戶 (預設: $DEFAULT_USER)"
echo " --port PORT 服務端口 (預設: $DEFAULT_PORT)"
echo ""
echo "範例:"
echo " $0 install --port 8080"
echo " $0 update"
echo " $0 status"
echo ""
}
# 函數:檢查是否為 root
check_root() {
if [ "$EUID" -ne 0 ]; then
log_error "請使用 root 權限執行此腳本"
log_info "使用: sudo $0 $@"
exit 1
fi
}
# 函數:檢查依賴
check_dependencies() {
log_info "檢查系統依賴..."
local missing=()
# 檢查 Python 3.10+
if command -v python3 &> /dev/null; then
local py_version=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
log_success "Python: $py_version"
else
missing+=("python3")
fi
# 檢查 pip
if ! command -v pip3 &> /dev/null; then
missing+=("python3-pip")
fi
# 檢查 venv
if ! python3 -c "import venv" &> /dev/null 2>&1; then
missing+=("python3-venv")
fi
if [ ${#missing[@]} -gt 0 ]; then
log_error "缺少依賴: ${missing[*]}"
log_info "請先安裝: apt install ${missing[*]}"
exit 1
fi
log_success "所有依賴已滿足"
}
# 函數:創建系統用戶
create_user() {
local username=$1
if id "$username" &>/dev/null; then
log_info "用戶 $username 已存在"
else
log_info "創建系統用戶: $username"
useradd --system --no-create-home --shell /bin/false "$username"
log_success "用戶 $username 已創建"
fi
}
# 函數:安裝後端
install_backend() {
local install_dir=$1
local username=$2
local port=$3
log_info "開始安裝 Meeting Assistant Backend..."
log_info "安裝目錄: $install_dir"
log_info "服務用戶: $username"
log_info "服務端口: $port"
echo ""
# 檢查依賴
check_dependencies
# 創建用戶
create_user "$username"
# 創建目錄
log_info "創建安裝目錄..."
mkdir -p "$install_dir"
mkdir -p "$install_dir/logs"
mkdir -p "$install_dir/templates"
mkdir -p "$install_dir/records"
# 複製後端代碼
log_info "複製後端代碼..."
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local source_dir="$(dirname "$script_dir")/backend"
if [ ! -d "$source_dir" ]; then
log_error "找不到後端源碼目錄: $source_dir"
exit 1
fi
cp -r "$source_dir/app" "$install_dir/"
cp "$source_dir/requirements.txt" "$install_dir/"
# 複製 .env.example 如果 .env 不存在
if [ ! -f "$install_dir/.env" ]; then
if [ -f "$source_dir/.env.example" ]; then
cp "$source_dir/.env.example" "$install_dir/.env"
log_warn "已創建 .env 檔案,請編輯配置: $install_dir/.env"
fi
fi
# 複製模板檔案
if [ -d "$source_dir/templates" ]; then
cp -r "$source_dir/templates/"* "$install_dir/templates/" 2>/dev/null || true
fi
# 創建虛擬環境
log_info "創建 Python 虛擬環境..."
python3 -m venv "$install_dir/venv"
# 安裝依賴
log_info "安裝 Python 依賴..."
"$install_dir/venv/bin/pip" install --upgrade pip
"$install_dir/venv/bin/pip" install -r "$install_dir/requirements.txt"
# 更新 .env 中的端口配置
if [ -f "$install_dir/.env" ]; then
sed -i "s/^BACKEND_PORT=.*/BACKEND_PORT=$port/" "$install_dir/.env"
fi
# 設置權限
log_info "設置檔案權限..."
chown -R "$username:$username" "$install_dir"
chmod 750 "$install_dir"
chmod 640 "$install_dir/.env" 2>/dev/null || true
# 創建 systemd 服務
create_systemd_service "$install_dir" "$username" "$port"
# 啟動服務
log_info "啟動服務..."
systemctl daemon-reload
systemctl enable meeting-assistant-backend
systemctl start meeting-assistant-backend
# 等待啟動
sleep 3
# 檢查狀態
if systemctl is-active --quiet meeting-assistant-backend; then
log_success "Meeting Assistant Backend 安裝成功!"
echo ""
echo "=========================================="
echo " 安裝完成"
echo "=========================================="
echo ""
echo " 服務狀態: systemctl status meeting-assistant-backend"
echo " 查看日誌: journalctl -u meeting-assistant-backend -f"
echo " API 地址: http://localhost:$port"
echo " API 文件: http://localhost:$port/docs"
echo ""
echo " 配置檔案: $install_dir/.env"
echo " 請確保已正確配置數據庫和 API 密鑰"
echo ""
else
log_error "服務啟動失敗,請檢查日誌"
journalctl -u meeting-assistant-backend --no-pager -n 20
exit 1
fi
}
# 函數:創建 systemd 服務檔案
create_systemd_service() {
local install_dir=$1
local username=$2
local port=$3
log_info "創建 systemd 服務..."
cat > /etc/systemd/system/meeting-assistant-backend.service << EOF
[Unit]
Description=Meeting Assistant Backend API
After=network.target
[Service]
Type=simple
User=$username
Group=$username
WorkingDirectory=$install_dir
Environment="PATH=$install_dir/venv/bin"
EnvironmentFile=$install_dir/.env
ExecStart=$install_dir/venv/bin/uvicorn app.main:app --host 0.0.0.0 --port $port
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=$install_dir/logs $install_dir/records $install_dir/templates
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
log_success "systemd 服務已創建"
}
# 函數:更新後端
update_backend() {
local install_dir=$1
log_info "更新 Meeting Assistant Backend..."
if [ ! -d "$install_dir" ]; then
log_error "安裝目錄不存在: $install_dir"
exit 1
fi
# 停止服務
log_info "停止服務..."
systemctl stop meeting-assistant-backend || true
# 備份配置
log_info "備份配置..."
cp "$install_dir/.env" "$install_dir/.env.backup" 2>/dev/null || true
# 複製新代碼
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
local source_dir="$(dirname "$script_dir")/backend"
log_info "更新代碼..."
rm -rf "$install_dir/app"
cp -r "$source_dir/app" "$install_dir/"
cp "$source_dir/requirements.txt" "$install_dir/"
# 更新依賴
log_info "更新依賴..."
"$install_dir/venv/bin/pip" install -r "$install_dir/requirements.txt"
# 恢復配置
if [ -f "$install_dir/.env.backup" ]; then
mv "$install_dir/.env.backup" "$install_dir/.env"
fi
# 重新設置權限
local username=$(stat -c '%U' "$install_dir")
chown -R "$username:$username" "$install_dir"
# 重啟服務
log_info "重啟服務..."
systemctl daemon-reload
systemctl start meeting-assistant-backend
sleep 2
if systemctl is-active --quiet meeting-assistant-backend; then
log_success "更新完成!"
else
log_error "服務重啟失敗"
exit 1
fi
}
# 函數:移除後端
uninstall_backend() {
local install_dir=$1
log_warn "即將移除 Meeting Assistant Backend"
read -p "確定要繼續嗎?(y/N) " confirm
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
log_info "取消移除"
exit 0
fi
# 停止並禁用服務
log_info "停止服務..."
systemctl stop meeting-assistant-backend 2>/dev/null || true
systemctl disable meeting-assistant-backend 2>/dev/null || true
# 刪除 systemd 服務
log_info "移除 systemd 服務..."
rm -f /etc/systemd/system/meeting-assistant-backend.service
systemctl daemon-reload
# 詢問是否刪除數據
read -p "是否刪除安裝目錄 $install_dir(y/N) " delete_dir
if [ "$delete_dir" = "y" ] || [ "$delete_dir" = "Y" ]; then
log_info "刪除安裝目錄..."
rm -rf "$install_dir"
else
log_info "保留安裝目錄: $install_dir"
fi
log_success "Meeting Assistant Backend 已移除"
}
# 函數:顯示狀態
show_status() {
echo ""
echo "=========================================="
echo " Meeting Assistant Backend 狀態"
echo "=========================================="
echo ""
if systemctl is-active --quiet meeting-assistant-backend; then
log_success "服務狀態: 運行中"
systemctl status meeting-assistant-backend --no-pager | grep -E "(Active|Main PID|Memory|CPU)"
else
log_warn "服務狀態: 未運行"
fi
echo ""
}
# 函數:顯示日誌
show_logs() {
journalctl -u meeting-assistant-backend -f
}
# 解析參數
INSTALL_DIR=$DEFAULT_INSTALL_DIR
SERVICE_USER=$DEFAULT_USER
SERVICE_PORT=$DEFAULT_PORT
COMMAND=""
while [[ $# -gt 0 ]]; do
case $1 in
install|update|uninstall|status|logs|help)
COMMAND=$1
shift
;;
--dir)
INSTALL_DIR="$2"
shift 2
;;
--user)
SERVICE_USER="$2"
shift 2
;;
--port)
SERVICE_PORT="$2"
shift 2
;;
*)
log_error "未知參數: $1"
show_help
exit 1
;;
esac
done
# 執行命令
case $COMMAND in
install)
check_root
install_backend "$INSTALL_DIR" "$SERVICE_USER" "$SERVICE_PORT"
;;
update)
check_root
update_backend "$INSTALL_DIR"
;;
uninstall)
check_root
uninstall_backend "$INSTALL_DIR"
;;
status)
show_status
;;
logs)
show_logs
;;
help|"")
show_help
;;
*)
log_error "未知命令: $COMMAND"
show_help
exit 1
;;
esac