368 lines
10 KiB
Bash
368 lines
10 KiB
Bash
#!/bin/bash
|
||
|
||
# ========================================
|
||
# 暫時規範管理系統 V3 - Linux 啟動腳本
|
||
# ========================================
|
||
|
||
set -e # 遇到錯誤立即退出
|
||
|
||
echo
|
||
echo "====================================="
|
||
echo "暫時規範管理系統 V3 - Linux 啟動"
|
||
echo "====================================="
|
||
echo
|
||
|
||
# 顏色定義
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# 檢查 Python 是否已安裝
|
||
if ! command -v python3 &> /dev/null; then
|
||
echo -e "${RED}[錯誤]${NC} Python3 未安裝"
|
||
echo "請安裝 Python 3.8+ 後重新執行此腳本"
|
||
echo
|
||
echo "Ubuntu/Debian: sudo apt update && sudo apt install python3 python3-pip python3-venv"
|
||
echo "CentOS/RHEL: sudo yum install python3 python3-pip"
|
||
echo "或使用包管理器安裝"
|
||
exit 1
|
||
fi
|
||
|
||
# 檢查 Docker 是否已安裝
|
||
if ! command -v docker &> /dev/null; then
|
||
echo -e "${YELLOW}[警告]${NC} Docker 未安裝或未運行"
|
||
echo "如需使用 Docker 模式,請先安裝 Docker"
|
||
echo
|
||
USE_DOCKER=false
|
||
else
|
||
# 檢查 Docker 是否運行
|
||
if ! docker info &> /dev/null; then
|
||
echo -e "${YELLOW}[警告]${NC} Docker 未運行"
|
||
echo "請啟動 Docker 服務: sudo systemctl start docker"
|
||
USE_DOCKER=false
|
||
else
|
||
USE_DOCKER=true
|
||
fi
|
||
fi
|
||
|
||
# 檢查 docker-compose 是否存在
|
||
if [[ "$USE_DOCKER" == true ]] && ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
|
||
echo -e "${YELLOW}[警告]${NC} docker-compose 未安裝"
|
||
USE_DOCKER=false
|
||
fi
|
||
|
||
# 檢查 .env 檔案
|
||
if [[ ! -f ".env" ]]; then
|
||
echo -e "${BLUE}[提示]${NC} 未找到 .env 檔案,正在複製範例檔案..."
|
||
cp ".env.example" ".env"
|
||
echo
|
||
echo -e "${YELLOW}[重要]${NC} 請編輯 .env 檔案並設定正確的參數值:"
|
||
echo "- 資料庫連線資訊"
|
||
echo "- LDAP/AD 伺服器設定"
|
||
echo "- SMTP 郵件伺服器設定"
|
||
echo
|
||
read -p "是否已完成 .env 檔案設定?(y/N): " confirm
|
||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||
echo "請先設定 .env 檔案後再執行此腳本"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
# 提供啟動選項
|
||
echo "請選擇啟動模式:"
|
||
echo
|
||
if [[ "$USE_DOCKER" == true ]]; then
|
||
echo "[1] Docker 容器化部署 (推薦)"
|
||
echo "[2] 本地 Python 直接執行"
|
||
echo "[3] 僅啟動外部服務 (MySQL + ONLYOFFICE)"
|
||
echo "[4] 生產環境部署 (含 Nginx)"
|
||
echo "[5] 系統服務安裝 (systemd)"
|
||
else
|
||
echo "[2] 本地 Python 直接執行"
|
||
echo "[5] 系統服務安裝 (systemd)"
|
||
echo
|
||
echo -e "${YELLOW}注意:Docker 相關選項不可用${NC}"
|
||
fi
|
||
echo
|
||
|
||
read -p "請輸入選項: " choice
|
||
|
||
case $choice in
|
||
1)
|
||
if [[ "$USE_DOCKER" != true ]]; then
|
||
echo -e "${RED}[錯誤]${NC} Docker 不可用,請選擇其他選項"
|
||
exit 1
|
||
fi
|
||
start_docker
|
||
;;
|
||
2)
|
||
start_manual
|
||
;;
|
||
3)
|
||
if [[ "$USE_DOCKER" != true ]]; then
|
||
echo -e "${RED}[錯誤]${NC} Docker 不可用,請選擇其他選項"
|
||
exit 1
|
||
fi
|
||
start_services_only
|
||
;;
|
||
4)
|
||
if [[ "$USE_DOCKER" != true ]]; then
|
||
echo -e "${RED}[錯誤]${NC} Docker 不可用,請選擇其他選項"
|
||
exit 1
|
||
fi
|
||
start_production
|
||
;;
|
||
5)
|
||
install_systemd_service
|
||
;;
|
||
*)
|
||
if [[ "$USE_DOCKER" == true ]]; then
|
||
start_docker
|
||
else
|
||
start_manual
|
||
fi
|
||
;;
|
||
esac
|
||
|
||
function start_docker() {
|
||
echo
|
||
echo "================================="
|
||
echo "使用 Docker Compose 啟動系統..."
|
||
echo "================================="
|
||
echo
|
||
|
||
# 檢查 compose 命令
|
||
if command -v docker-compose &> /dev/null; then
|
||
COMPOSE_CMD="docker-compose"
|
||
else
|
||
COMPOSE_CMD="docker compose"
|
||
fi
|
||
|
||
# 停止並清理舊的容器
|
||
echo -e "${BLUE}[步驟 1]${NC} 清理舊容器..."
|
||
$COMPOSE_CMD down
|
||
|
||
# 重新構建並啟動服務
|
||
echo -e "${BLUE}[步驟 2]${NC} 構建並啟動服務..."
|
||
$COMPOSE_CMD up --build -d
|
||
|
||
# 等待服務啟動
|
||
echo -e "${BLUE}[步驟 3]${NC} 等待服務啟動..."
|
||
sleep 30
|
||
|
||
# 初始化資料庫
|
||
echo -e "${BLUE}[步驟 4]${NC} 初始化資料庫..."
|
||
$COMPOSE_CMD exec -T app python init_db.py --auto-yes || true
|
||
|
||
# 顯示狀態
|
||
echo -e "${BLUE}[步驟 5]${NC} 檢查服務狀態..."
|
||
$COMPOSE_CMD ps
|
||
|
||
echo
|
||
echo -e "${GREEN}============================"
|
||
echo "系統啟動完成!"
|
||
echo "============================${NC}"
|
||
echo
|
||
echo "服務訪問地址:"
|
||
echo "- 主系統:http://localhost:5000"
|
||
echo "- ONLYOFFICE:http://localhost:8080"
|
||
echo "- MySQL:localhost:3306"
|
||
echo
|
||
echo "管理命令:"
|
||
echo "- 查看日誌:$COMPOSE_CMD logs -f"
|
||
echo "- 停止服務:$COMPOSE_CMD down"
|
||
echo "- 重啟服務:$COMPOSE_CMD restart"
|
||
echo
|
||
}
|
||
|
||
function start_services_only() {
|
||
echo
|
||
echo "==============================="
|
||
echo "僅啟動外部服務..."
|
||
echo "==============================="
|
||
echo
|
||
|
||
if command -v docker-compose &> /dev/null; then
|
||
COMPOSE_CMD="docker-compose"
|
||
else
|
||
COMPOSE_CMD="docker compose"
|
||
fi
|
||
|
||
$COMPOSE_CMD up -d mysql onlyoffice
|
||
|
||
echo
|
||
echo -e "${GREEN}外部服務已啟動!${NC}"
|
||
echo "- MySQL:localhost:3306"
|
||
echo "- ONLYOFFICE:http://localhost:8080"
|
||
echo
|
||
echo "請使用以下命令啟動 Flask 應用:"
|
||
echo "python3 app.py"
|
||
echo
|
||
}
|
||
|
||
function start_production() {
|
||
echo
|
||
echo "==============================="
|
||
echo "生產環境部署 (含 Nginx)..."
|
||
echo "==============================="
|
||
echo
|
||
|
||
if command -v docker-compose &> /dev/null; then
|
||
COMPOSE_CMD="docker-compose"
|
||
else
|
||
COMPOSE_CMD="docker compose"
|
||
fi
|
||
|
||
$COMPOSE_CMD --profile production up --build -d
|
||
|
||
echo
|
||
echo -e "${GREEN}生產環境已啟動!${NC}"
|
||
echo "- 系統入口:http://localhost (透過 Nginx)"
|
||
echo "- 直接訪問:http://localhost:5000"
|
||
echo
|
||
}
|
||
|
||
function start_manual() {
|
||
echo
|
||
echo "==============================="
|
||
echo "本地 Python 環境啟動..."
|
||
echo "==============================="
|
||
echo
|
||
|
||
# 檢查虛擬環境
|
||
if [[ -d "venv" ]]; then
|
||
echo -e "${BLUE}[步驟 1]${NC} 啟用虛擬環境..."
|
||
source venv/bin/activate
|
||
else
|
||
echo -e "${YELLOW}[警告]${NC} 未找到虛擬環境,建議先建立:"
|
||
echo "python3 -m venv venv"
|
||
echo "source venv/bin/activate"
|
||
echo "pip install -r requirements.txt"
|
||
echo
|
||
read -p "是否立即建立虛擬環境?(y/N): " create_venv
|
||
if [[ "$create_venv" =~ ^[Yy]$ ]]; then
|
||
python3 -m venv venv
|
||
source venv/bin/activate
|
||
echo -e "${GREEN}虛擬環境已建立並啟用${NC}"
|
||
fi
|
||
fi
|
||
|
||
# 安裝依賴
|
||
echo -e "${BLUE}[步驟 2]${NC} 檢查並安裝依賴..."
|
||
pip install -r requirements.txt
|
||
|
||
# 檢查外部服務
|
||
echo -e "${BLUE}[步驟 3]${NC} 檢查外部服務..."
|
||
echo
|
||
echo -e "${YELLOW}[重要提醒]${NC} 請確保以下服務已啟動:"
|
||
echo
|
||
echo "1. MySQL 資料庫伺服器"
|
||
echo " - 可使用: docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0"
|
||
echo
|
||
echo "2. ONLYOFFICE Document Server"
|
||
echo " - 可使用: docker run -d -p 8080:80 onlyoffice/documentserver"
|
||
echo
|
||
echo "3. LDAP/AD 伺服器 (如果適用)"
|
||
echo "4. SMTP 郵件伺服器 (如果適用)"
|
||
echo
|
||
|
||
read -p "外部服務是否已準備就緒?(y/N): " confirm
|
||
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
|
||
echo "請先啟動必要的外部服務"
|
||
exit 1
|
||
fi
|
||
|
||
# 初始化資料庫
|
||
echo -e "${BLUE}[步驟 4]${NC} 初始化資料庫..."
|
||
python3 init_db.py || python init_db.py
|
||
|
||
# 啟動應用
|
||
echo -e "${BLUE}[步驟 5]${NC} 啟動 Flask 應用..."
|
||
echo
|
||
echo "啟動中... (Ctrl+C 停止)"
|
||
echo "訪問地址: http://localhost:5000"
|
||
echo
|
||
|
||
# 根據系統環境選擇啟動方式
|
||
if command -v gunicorn &> /dev/null; then
|
||
echo "使用 Gunicorn 啟動生產模式..."
|
||
gunicorn -w 4 -b 0.0.0.0:5000 app:app
|
||
else
|
||
echo "使用 Flask 開發伺服器啟動..."
|
||
python3 app.py || python app.py
|
||
fi
|
||
}
|
||
|
||
function install_systemd_service() {
|
||
echo
|
||
echo "==============================="
|
||
echo "安裝為系統服務 (systemd)..."
|
||
echo "==============================="
|
||
echo
|
||
|
||
# 檢查是否為 root 用戶
|
||
if [[ $EUID -ne 0 ]]; then
|
||
echo -e "${RED}[錯誤]${NC} 需要 root 權限安裝系統服務"
|
||
echo "請使用 sudo 執行此腳本"
|
||
exit 1
|
||
fi
|
||
|
||
# 獲取當前目錄和用戶
|
||
CURRENT_DIR=$(pwd)
|
||
CURRENT_USER=${SUDO_USER:-$USER}
|
||
|
||
echo "安裝目錄: $CURRENT_DIR"
|
||
echo "執行用戶: $CURRENT_USER"
|
||
echo
|
||
|
||
# 建立服務檔案
|
||
cat > /etc/systemd/system/tempspec.service << EOF
|
||
[Unit]
|
||
Description=Temp Spec System V3
|
||
After=network.target mysql.service
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=$CURRENT_USER
|
||
Group=$CURRENT_USER
|
||
WorkingDirectory=$CURRENT_DIR
|
||
Environment=PATH=$CURRENT_DIR/venv/bin
|
||
ExecStart=$CURRENT_DIR/venv/bin/gunicorn -w 4 -b 0.0.0.0:5000 app:app
|
||
ExecReload=/bin/kill -HUP \$MAINPID
|
||
Restart=always
|
||
RestartSec=3
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
# 重新載入 systemd
|
||
systemctl daemon-reload
|
||
|
||
# 啟用服務
|
||
systemctl enable tempspec.service
|
||
|
||
echo -e "${GREEN}系統服務安裝完成!${NC}"
|
||
echo
|
||
echo "管理命令:"
|
||
echo "- 啟動服務: sudo systemctl start tempspec"
|
||
echo "- 停止服務: sudo systemctl stop tempspec"
|
||
echo "- 重啟服務: sudo systemctl restart tempspec"
|
||
echo "- 查看狀態: sudo systemctl status tempspec"
|
||
echo "- 查看日誌: sudo journalctl -u tempspec -f"
|
||
echo
|
||
|
||
read -p "是否立即啟動服務?(y/N): " start_now
|
||
if [[ "$start_now" =~ ^[Yy]$ ]]; then
|
||
systemctl start tempspec
|
||
systemctl status tempspec --no-pager
|
||
fi
|
||
}
|
||
|
||
# 捕捉 Ctrl+C
|
||
trap 'echo -e "\n${YELLOW}操作已取消${NC}"; exit 130' INT
|
||
|
||
echo
|
||
echo -e "${GREEN}腳本執行完成!${NC}" |