2025-11-14 13:38:37 +08:00
|
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
# filepath: deploy.sh
|
2025-11-14 13:49:09 +08:00
|
|
|
|
# git clone https://code.deep-pilot.chat/AI_POC/TERES_web_frontend.git
|
2025-11-14 13:38:37 +08:00
|
|
|
|
|
2025-11-14 13:49:09 +08:00
|
|
|
|
set -e
|
|
|
|
|
|
if [ -n "${BASH_VERSION:-}" ]; then
|
|
|
|
|
|
set -o pipefail
|
|
|
|
|
|
fi
|
2025-11-14 13:38:37 +08:00
|
|
|
|
|
|
|
|
|
|
# 固定镜像名(兼容你原 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 "$@"
|