該腳本用于自動化安裝 Open WebUI,并支持以下功能:
可選跳過 Ollama 安裝:通過 --no-ollama 參數跳過 Ollama 的安裝。自動清理舊目錄:如果安裝目錄 (~/open-webui) 已存在,腳本會自動刪除舊目錄并重新安裝。完整的依賴安裝:包括 Python、Node.js、npm、Git 等依賴的安裝。自動配置系統服務:將 Open WebUI 配置為系統服務,并設置開機自啟。防火墻配置:自動開放端口 8080,以便訪問 Open WebUI。
更新后的腳本:
bash
復制
#!/bin/bash# 遇到錯誤時退出腳本
set -e# 檢查并設置 Conda
setup_conda() {# 如果 conda 命令不可用,但目錄存在if [ -d "$HOME/miniconda" ]; thenecho "檢測到已存在的 Miniconda 安裝,正在配置..."# 添加到 PATHexport PATH="$HOME/miniconda/bin:$PATH"# 初始化 bash 和 condaif [ ! -f "$HOME/.bashrc" ] || ! grep -q "conda initialize" "$HOME/.bashrc"; then"$HOME/miniconda/bin/conda" init bashsource "$HOME/.bashrc"fielseecho "正在安裝 Miniconda..."# 下載 Miniconda 安裝腳本wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh# 安裝 Minicondabash miniconda.sh -b -p "$HOME/miniconda"# 初始化 bash 和 condaexport PATH="$HOME/miniconda/bin:$PATH""$HOME/miniconda/bin/conda" init bashsource "$HOME/.bashrc"fi
}# 生成隨機密鑰的函數
generate_secret_key() {python3 -c 'import secrets; print(secrets.token_urlsafe(32))'
}# 顯示腳本用法
usage() {echo "用法: $0 [--no-ollama] [--no-download]"echo " --no-ollama: 跳過 Ollama 安裝"echo " --no-download: 跳過下載 Open WebUI 代碼(如果已經下載)"exit 1
}# 解析參數
SKIP_OLLAMA=false
SKIP_DOWNLOAD=false
while [[ $# -gt 0 ]]; docase "$1" in--no-ollama)SKIP_OLLAMA=trueshift;;--no-download)SKIP_DOWNLOAD=trueshift;;*)usage;;esac
done# 檢查 sudo 權限
check_sudo() {if ! sudo -n true 2>/dev/null; thenecho "需要 sudo 權限來安裝系統依賴。"echo "請確保你有 sudo 權限,或者以 root 用戶運行此腳本。"exit 1fi
}echo "開始安裝 Open WebUI..."# 檢查 sudo 權限
check_sudo# 更新系統包
echo "更新系統包..."
if command -v apt-get &> /dev/null; thensudo -n apt-get updatesudo -n apt-get upgrade -y
fi# 安裝基本依賴
echo "安裝基本依賴..."
sudo -n apt-get install -y python3 python3-pip git curl python3-venv build-essential || { echo "安裝依賴失敗"; exit 1; }# 安裝 Node.js
echo "安裝 Node.js..."
if ! command -v node &> /dev/null; thenecho "安裝 Node.js 20 LTS..."# 添加 NodeSource 倉庫if [ ! -f "/etc/apt/sources.list.d/nodesource.list" ]; thenecho "添加 NodeSource 倉庫..."curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo -n gpg --dearmor -o /usr/share/keyrings/nodesource.gpgecho "deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | sudo -n tee /etc/apt/sources.list.d/nodesource.listsudo -n apt-get updatefi# 安裝 Node.jssudo -n apt-get install -y nodejs# 驗證安裝if ! command -v node &> /dev/null; thenecho "Node.js 安裝失敗"exit 1fi
fi# 顯示 Node.js 版本
echo "Node.js 版本:"
node --version
echo "npm 版本:"
npm --version# 安裝 Ollama(如果不跳過)
if [[ "$SKIP_OLLAMA" = false ]]; thenecho "安裝 Ollama..."curl -fsSL https://ollama.com/install.sh | sh || { echo "Ollama 安裝失敗"; exit 1; }sudo systemctl enable ollamasudo systemctl start ollama
elseecho "跳過 Ollama 安裝。"
fi# 檢查 CUDA 環境
check_cuda() {echo "檢查 CUDA 環境..."if ! command -v nvidia-smi &> /dev/null; thenecho "警告: 未檢測到 NVIDIA GPU 驅動"return 1elseecho "GPU 信息:"nvidia-smi --query-gpu=gpu_name,driver_version,memory.total,memory.free,memory.used,temperature.gpu --format=csv,noheaderreturn 0fi
}# 設置 CUDA 環境
setup_cuda() {# 檢查 CUDA 是否已安裝if [ -d "/usr/local/cuda-11.4" ]; thenecho "CUDA 11.4 已安裝在 /usr/local/cuda-11.4"# 設置環境變量if ! grep -q "export PATH=/usr/local/cuda-11.4/bin" ~/.bashrc; thenecho 'export PATH=/usr/local/cuda-11.4/bin:$PATH' >> ~/.bashrcfiif ! grep -q "export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64" ~/.bashrc; thenecho 'export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH' >> ~/.bashrcfisource ~/.bashrcreturn 0# 如果沒有安裝且沒有 nvcc 命令elif ! command -v nvcc &> /dev/null; thenecho "未檢測到 CUDA toolkit,正在安裝..."# 檢查安裝文件是否已存在CUDA_INSTALLER="cuda_11.4.4_470.82.01_linux.run"if [ ! -f "$CUDA_INSTALLER" ]; thenecho "下載 CUDA 11.4 安裝包..."wget https://developer.download.nvidia.com/compute/cuda/11.4.4/local_installers/$CUDA_INSTALLERelseecho "CUDA 安裝包已存在,跳過下載..."fiecho "安裝 CUDA toolkit..."sudo sh $CUDA_INSTALLER --toolkit --silent --override# 設置環境變量if ! grep -q "export PATH=/usr/local/cuda-11.4/bin" ~/.bashrc; thenecho 'export PATH=/usr/local/cuda-11.4/bin:$PATH' >> ~/.bashrcfiif ! grep -q "export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64" ~/.bashrc; thenecho 'export LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH' >> ~/.bashrcfisource ~/.bashrcreturn 0fireturn 1
}# 檢查 GPU 和設置 CUDA
if check_cuda; thenecho "檢測到 GPU,設置 CUDA 環境..."setup_cuda# 設置 GPU 相關環境變量export NODE_ONNX_RUNTIME_GPU=1export CUDA_VISIBLE_DEVICES=0# 顯示 CUDA 版本echo "CUDA 版本: $(nvidia-smi | grep "CUDA Version" | awk '{print $9}')"# 下載 GPU 版本的 onnxruntimeecho "下載 onnxruntime GPU 版本..."mkdir -p node_modules/onnxruntime-node/bin/napi-v3/linux/x64cd node_modules/onnxruntime-node/bin/napi-v3/linux/x64# 嘗試多個下載源download_file() {local urls=("https://mirror.ghproxy.com/https://github.com/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-gpu-1.20.1.tgz""https://hub.fastgit.xyz/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-gpu-1.20.1.tgz""https://github.com/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-gpu-1.20.1.tgz")for url in "${urls[@]}"; doecho "嘗試從 $url 下載..."wget --no-check-certificate \--timeout=15 \--tries=3 \--continue \--inet4-only \-q --show-progress \"$url" && return 0echo "從 $url 下載失敗,嘗試下一個源..."donereturn 1}if ! download_file; thenecho "GPU 版本下載失敗,切換到 CPU 模式..."export NODE_ONNX_RUNTIME_GPU=0elseecho "解壓 GPU 版本文件..."tar xzf onnxruntime-linux-x64-gpu-1.20.1.tgzficd -
elseecho "未檢測到 GPU,將使用 CPU 模式..."export NODE_ONNX_RUNTIME_GPU=0# 下載 CPU 版本的 onnxruntimeecho "下載 onnxruntime CPU 版本..."mkdir -p node_modules/onnxruntime-node/bin/napi-v3/linux/x64cd node_modules/onnxruntime-node/bin/napi-v3/linux/x64wget --no-check-certificate \--timeout=15 \--tries=3 \--continue \--inet4-only \-q --show-progress \"https://github.com/microsoft/onnxruntime/releases/download/v1.20.1/onnxruntime-linux-x64-1.20.1.tgz"if [ $? -eq 0 ]; thenecho "解壓 CPU 版本文件..."tar xzf onnxruntime-linux-x64-1.20.1.tgzelseecho "警告: onnxruntime CPU 版本下載失敗"ficd -
fi# 臨時設置環境變量
if [ -d "/usr/local/cuda-11.4" ]; thenexport PATH=/usr/local/cuda-11.4/bin:$PATHexport LD_LIBRARY_PATH=/usr/local/cuda-11.4/lib64:$LD_LIBRARY_PATH
fi# 檢查是否已經在虛擬環境中
if [ -z "$VIRTUAL_ENV" ]; then# 如果不在虛擬環境中,則檢查并設置 Condaif ! command -v conda &> /dev/null; thenecho "Conda 未安裝或不在 PATH 中,正在設置..."setup_condafi# 再次檢查 conda 是否可用if ! command -v conda &> /dev/null; thenecho "Conda 安裝失敗,請手動安裝 Conda 后重試"exit 1fi# 確保 conda 命令可用source "$HOME/.bashrc"eval "$(conda shell.bash hook)"# 檢查并刪除已存在的環境if conda env list | grep -q "^open-webui "; thenecho "刪除已存在的 open-webui 環境..."conda deactivateconda env remove -n open-webui -yfi# 創建并激活 Python 3.11 環境echo "創建 Python 3.11 環境..."conda create -y -n open-webui python=3.11source activate open-webui || conda activate open-webui
elseecho "檢測到已存在的虛擬環境: $VIRTUAL_ENV"echo "跳過創建新環境..."
fi# 驗證 Python 環境
echo "驗證 Python 環境..."
which python
python --version# 創建安裝目錄
echo "設置 Open WebUI 安裝目錄..."
INSTALL_DIR="/opt/open-webui"
mkdir -p "$INSTALL_DIR"# 下載或更新 Open WebUI
if [[ "$SKIP_DOWNLOAD" = false ]]; thenecho "下載 Open WebUI..."if [ -d "$INSTALL_DIR/open-webui" ]; thenecho "更新 Open WebUI..."cd "$INSTALL_DIR/open-webui"git pullelseecho "克隆 Open WebUI..."cd "$INSTALL_DIR"git clone https://github.com/open-webui/open-webui.gitfi
elseecho "跳過下載 Open WebUI..."if [ ! -d "$INSTALL_DIR/open-webui" ]; thenecho "錯誤:Open WebUI 目錄不存在于 $INSTALL_DIR/open-webui"echo "請確保目錄存在或移除 --no-download 選項"exit 1fi
fi# 設置權限
echo "設置目錄權限..."
sudo -n chown -R $USER:$USER "$INSTALL_DIR"# 進入項目目錄
cd "$INSTALL_DIR/open-webui"# 安裝系統依賴
echo "安裝系統依賴..."
if command -v apt-get &> /dev/null; thensudo -n apt-get updatesudo -n apt-get install -y ffmpeg
elif command -v yum &> /dev/null; thensudo -n yum install -y ffmpeg
elif command -v pacman &> /dev/null; thensudo -n pacman -S --noconfirm ffmpeg
elif command -v apk &> /dev/null; thensudo -n apk add --no-cache ffmpeg
elseecho "警告: 無法識別的包管理器,請手動安裝 ffmpeg"
fi# 構建前端
echo "構建前端..."
cd /opt/open-webui/open-webuiecho "清理舊的構建文件..."
rm -rf node_modules package-lock.jsonecho "配置 npm..."
npm config set registry https://registry.npmmirror.com
npm config set fetch-retries 5
npm config set fetch-timeout 60000
npm config set progress true
npm config set loglevel infoecho "安裝前端依賴..."
# 使用 pnpm 或 npm 安裝依賴
if command -v pnpm &> /dev/null; thenecho "使用 pnpm 安裝依賴..."# 配置 pnpm 使用淘寶鏡像pnpm config set registry https://registry.npmmirror.compnpm install --reporter=default
elseecho "使用 npm 安裝依賴..."npm install --verbose
fi# 構建前端
echo "構建前端..."
if command -v pnpm &> /dev/null; thenpnpm run build --reporter=default
elsenpm run build --verbose
fi# 檢查構建結果
if [ -d "build" ]; thenecho "前端構建成功!"
elseecho "前端構建失敗,請檢查錯誤信息"exit 1
fi# 初始化數據庫
echo "初始化數據庫..."
cd backend
export PYTHONPATH=/opt/open-webui/open-webui/backend# 運行數據庫遷移
echo "運行數據庫遷移..."
if [ -f "open_webui/alembic.ini" ]; thencd open_webuiecho "當前目錄: $(pwd)"echo "運行遷移..."alembic upgrade headcd ..
elseecho "在以下位置搜索 alembic.ini:"find . -name "alembic.ini" -type fecho "錯誤: 找不到 alembic.ini"exit 1
fi# 確保 .webui_secret_key 存在
if [ ! -f ".webui_secret_key" ]; thenecho "生成 secret key..."head -c 12 /dev/random | base64 > .webui_secret_key
fi# 設置環境變量
export WEBUI_SECRET_KEY=$(cat .webui_secret_key)
export PORT=8111
export HOST=0.0.0.0# 啟動服務
if command -v gunicorn &> /dev/null; thenecho "使用 gunicorn 啟動..."gunicorn -w 1 -k uvicorn.workers.UvicornWorker "open_webui.main:app" \--bind 0.0.0.0:8111 \--timeout 300 \--log-level debug \--error-logfile - \--capture-output &# 保存進程 IDGUNICORN_PID=$!echo "Gunicorn PID: $GUNICORN_PID"
elseecho "使用 uvicorn 啟動..."python -m uvicorn "open_webui.main:app" \--host 0.0.0.0 \--port 8111 \--log-level debug &# 保存進程 IDUVICORN_PID=$!echo "Uvicorn PID: $UVICORN_PID"
fi# 等待后端啟動
echo "等待服務啟動..."
for i in {1..30}; doif curl -s http://localhost:8111/health > /dev/null; thenecho "服務已啟動成功!"echo "請訪問 http://localhost:8111"breakfi# 檢查進程是否還在運行if [ ! -z "$GUNICORN_PID" ] && ! ps -p $GUNICORN_PID > /dev/null; thenecho "錯誤: Gunicorn 進程已退出"breakfiif [ ! -z "$UVICORN_PID" ] && ! ps -p $UVICORN_PID > /dev/null; thenecho "錯誤: Uvicorn 進程已退出"breakfiecho "嘗試 $i/30..."sleep 1
done# 如果服務沒有啟動,顯示調試信息
if ! curl -s http://localhost:8111/health > /dev/null; thenecho "服務啟動失敗,顯示調試信息:"echo "Python 路徑: $PYTHONPATH"echo "當前目錄: $(pwd)"echo "Python 版本: $(python --version)"echo "已安裝的包:"pip listecho "目錄內容:"ls -laecho "open_webui 目錄內容:"ls -la open_webui/echo "進程狀態:"ps aux | grep -E "gunicorn|uvicorn"echo "端口狀態:"netstat -tuln | grep 8111echo "日志內容:"tail -n 50 /var/log/syslog | grep -E "gunicorn|uvicorn|open_webui"
fi# 創建系統服務
echo "創建系統服務..."
sudo tee /etc/systemd/system/open-webui-backend.service << EOL
[Unit]
Description=Open WebUI Backend
After=network.target[Service]
Type=simple
User=$USER
WorkingDirectory=/opt/open-webui/open-webui/backend
ExecStart=/opt/open-webui/open-webui/venv/bin/gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app --bind 0.0.0.0:8111
Environment="PATH=/opt/open-webui/open-webui/venv/bin"
Restart=on-failure
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=open-webui-backend[Install]
WantedBy=multi-user.target
EOL# 啟動并啟用服務
echo "啟動 Open WebUI 服務..."
sudo systemctl daemon-reload
sudo systemctl enable open-webui-backend
sudo systemctl start open-webui-backend# 配置防火墻
echo "配置防火墻..."
sudo ufw allow 8111/tcpecho "安裝成功完成!"
echo "您現在可以通過 http://localhost:8111 訪問 Open WebUI。"
echo "首次訪問時,請創建一個管理員賬戶。"
使用方法:
將腳本保存為文件,例如 install_open_webui.sh。賦予腳本執行權限:
bash
復制chmod +x install_open_webui.sh運行腳本:默認安裝(包含 Ollama):bash復制./install_open_webui.sh跳過 Ollama 安裝:bash復制./install_open_webui.sh --no-ollama
注意事項:
確保您具有 sudo 權限來運行腳本。如果安裝失敗,可以通過以下命令查看服務日志:
bash
復制sudo journalctl -u open-webui-backend如果前端構建失敗,請確保已正確安裝 nodejs 和 npm,然后手動運行以下命令:
bash
復制npm install
npm run build
如果有其他問題,歡迎隨時提問!