Files
TERES_web_frontend/deploy.sh

213 lines
5.5 KiB
Bash
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.

#!/usr/bin/env bash
# filepath: deploy.sh
# git clone https://code.deep-pilot.chat/AI_POC/TERES_web_frontend.git
set -e
if [ -n "${BASH_VERSION:-}" ]; then
set -o pipefail
fi
# 固定镜像名(兼容你原 stop.sh 的做法)
IMAGE_NAME="teres_web_frontend:latest"
FLASK_IMAGE_NAME="teres_web_frontend_flask:latest"
SERVICE_NAME="teres_web_frontend"
NETWORK_NAME="proxy-net"
usage() {
cat <<'EOF'
用法: ./deploy.sh <命令> [选项]
常用命令:
start 拉最新代码并构建启动docker compose up -d --build
stop 按固定镜像名停止并删除容器,同时删除镜像
restart 先 stop 再 start
clean 同 stop停止容器并删除镜像
增强命令:
status 查看服务状态compose ps + 过滤容器)
logs [--follow] 查看日志(加 --follow 跟随)
health 健康检查HTTP 200
set [opts] 更新 .env 中 PORT/BUILD_MODE/RAGFLOW_BASE
pull 仅拉取最新代码
prune 清理悬空镜像与缓存
set 支持的选项:
--port <N> 设置端口(映射和构建参数)
--mode <production|flask> 设置构建模式,选择 .env.production 或 .env.flask
--base <path> 设置 ragflow 子路径(默认 /ragflow/
示例:
./deploy.sh start
./deploy.sh set --port 5173 --mode production --base /ragflow/
./deploy.sh logs --follow
./deploy.sh health
EOF
}
# 检查命令存在
require_cmd() {
local cmd="$1"; command -v "$cmd" >/dev/null 2>&1 || {
echo "错误: 未找到命令 '$cmd'"; exit 1; }
}
# 选择 compose 命令
compose_cmd() {
if command -v docker-compose >/dev/null 2>&1; then
echo docker-compose
else
echo docker compose
fi
}
ensure_network() {
if ! docker network inspect "$NETWORK_NAME" >/dev/null 2>&1; then
echo "--- 创建网络: $NETWORK_NAME ---"
docker network create "$NETWORK_NAME"
fi
}
git_pull() {
echo "--- 拉取最新的代码 ---"
git fetch --all --prune || true
git pull
}
compose_up() {
local cmd; cmd=$(compose_cmd)
ensure_network
echo "--- docker compose 构建并启动 ---"
$cmd up -d --build
}
compose_down() {
local cmd; cmd=$(compose_cmd)
echo "--- docker compose down ---"
$cmd down || true
}
stop_by_image() {
local image="$1"
echo "--- 停止并删除镜像对应的容器: $image ---"
local ids
ids=$(docker ps -a --filter "ancestor=$image" --format "{{.ID}}" || true)
if [[ -n "$ids" ]]; then
for id in $ids; do
docker stop "$id" || true
docker rm "$id" || true
done
fi
echo "--- 删除镜像: $image ---"
docker rmi "$image" || true
}
status() {
local cmd; cmd=$(compose_cmd)
echo "--- compose ps ---"
$cmd ps || true
echo "--- docker ps (过滤 $SERVICE_NAME) ---"
docker ps --format '{{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Status}}' | grep -E "$SERVICE_NAME|$IMAGE_NAME" || true
}
logs() {
local follow="false"
if [[ "${1:-}" == "--follow" ]]; then follow="true"; fi
local cmd; cmd=$(compose_cmd)
if [[ "$follow" == "true" ]]; then
$cmd logs -f "$SERVICE_NAME"
else
$cmd logs --tail=300 "$SERVICE_NAME"
fi
}
# 更新 .env 中某个键值(若不存在则追加)
update_env_var() {
local key="$1"; shift
local val="$1"; shift
touch .env
if grep -qE "^\s*${key}\s*=\s*" .env; then
# 使用正则替换整行,保留键名
sed -i.bak -E "s|^\s*(${key})\s*=\s*.*|\1=${val}|" .env
else
echo "${key}=${val}" >> .env
fi
}
health() {
# 从 .env 读取,带默认值
local PORT=${PORT:-$(grep -E '^\s*PORT\s*=' .env | sed -E 's/.*=\s*//g' || echo 5173)}
local BASE=${RAGFLOW_BASE:-$(grep -E '^\s*RAGFLOW_BASE\s*=' .env | sed -E 's/.*=\s*//g' || echo /ragflow/)}
local host="http://127.0.0.1:${PORT}"
echo "--- 健康检查: ${host}${host}${BASE} ---"
if command -v curl >/dev/null 2>&1; then
curl -fsS -o /dev/null "${host}" && echo "根应用 OK" || echo "根应用失败"
curl -fsS -o /dev/null "${host}${BASE}" && echo "ragflow 子路径 OK" || echo "ragflow 子路径失败"
else
wget -q --spider "${host}" && echo "根应用 OK" || echo "根应用失败"
wget -q --spider "${host}${BASE}" && echo "ragflow 子路径 OK" || echo "ragflow 子路径失败"
fi
}
prune() {
echo "--- 清理悬空镜像与构建缓存 ---"
docker image prune -f || true
docker builder prune -f || true
}
cmd_start() {
git_pull
compose_up
}
cmd_stop() {
compose_down
stop_by_image "$IMAGE_NAME"
stop_by_image "$FLASK_IMAGE_NAME"
}
cmd_restart() {
cmd_stop
cmd_start
}
cmd_clean() { cmd_stop; }
cmd_pull() { git_pull; }
cmd_set() {
# 解析选项
local port="" mode="" base=""
while [[ $# -gt 0 ]]; do
case "$1" in
--port) port="$2"; shift 2;;
--mode) mode="$2"; shift 2;;
--base) base="$2"; shift 2;;
*) echo "未知选项: $1"; usage; exit 1;;
esac
done
[[ -n "$port" ]] && update_env_var PORT "$port"
[[ -n "$mode" ]] && update_env_var BUILD_MODE "$mode"
[[ -n "$base" ]] && update_env_var RAGFLOW_BASE "$base"
echo "--- .env 已更新 ---"
}
main() {
require_cmd docker
local subcmd="${1:-}"
case "$subcmd" in
start) shift; cmd_start "$@" ;;
stop) shift; cmd_stop "$@" ;;
restart) shift; cmd_restart "$@" ;;
clean) shift; cmd_clean "$@" ;;
status) shift; status "$@" ;;
logs) shift; logs "${1:-}" ;;
health) shift; health "$@" ;;
set) shift; cmd_set "$@" ;;
pull) shift; cmd_pull "$@" ;;
prune) shift; prune "$@" ;;
""|help|-h|--help) usage ;;
*) echo "未知命令: $subcmd"; usage; exit 1 ;;
esac
echo "--- 完成 ---"
}
main "$@"