Files
xingrin/docker/start.sh

199 lines
6.1 KiB
Bash
Raw Normal View History

2025-12-12 18:04:57 +08:00
#!/bin/bash
set -e
cd "$(dirname "$0")"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
# 解析参数
WITH_FRONTEND=true
DEV_MODE=false
QUIET_MODE=false
2025-12-12 18:04:57 +08:00
for arg in "$@"; do
case $arg in
--no-frontend) WITH_FRONTEND=false ;;
--dev) DEV_MODE=true ;;
--quiet) QUIET_MODE=true ;;
2025-12-12 18:04:57 +08:00
esac
done
# 选择 compose 文件
if [ "$DEV_MODE" = true ]; then
COMPOSE_FILE="docker-compose.dev.yml"
echo -e "${YELLOW}[MODE]${NC} 开发模式 - 本地构建镜像"
else
COMPOSE_FILE="docker-compose.yml"
echo -e "${GREEN}[MODE]${NC} 生产模式 - 使用 Docker Hub 镜像"
fi
# 检查 Docker 环境
if ! command -v docker >/dev/null 2>&1; then
echo -e "${RED}[ERROR]${NC} 未检测到 docker 命令,请先安装 Docker"
exit 1
fi
if ! docker info >/dev/null 2>&1; then
echo -e "${RED}[ERROR]${NC} Docker 守护进程未运行,请先启动 Docker"
exit 1
fi
if docker compose version >/dev/null 2>&1; then
2025-12-12 18:04:57 +08:00
COMPOSE_CMD="docker compose"
elif command -v docker-compose >/dev/null 2>&1; then
COMPOSE_CMD="docker-compose"
2025-12-12 18:04:57 +08:00
else
echo -e "${RED}[ERROR]${NC} 未检测到 docker compose请先安装"
exit 1
fi
# 检查配置文件
if [ ! -f .env ]; then
echo -e "${RED}[ERROR]${NC} 未找到 .env 配置文件"
echo " 请先复制 .env.example 为 .env 并配置"
exit 1
fi
# 确保数据目录存在
DATA_DIR="/opt/xingrin"
if [ ! -d "$DATA_DIR/results" ] || [ ! -d "$DATA_DIR/logs" ]; then
echo -e "${CYAN}[INIT]${NC} 创建数据目录: $DATA_DIR"
sudo mkdir -p "$DATA_DIR/results" "$DATA_DIR/logs"
sudo chmod -R 755 "$DATA_DIR"
fi
# 读取数据库配置
DB_HOST=$(grep -E "^DB_HOST=" .env | cut -d'=' -f2 | tr -d ' "'"'" || echo "postgres")
if [[ "$DB_HOST" == "postgres" || "$DB_HOST" == "localhost" || "$DB_HOST" == "127.0.0.1" ]]; then
echo -e "${CYAN}[DB]${NC} 使用本地 PostgreSQL 容器"
PROFILE_ARG="--profile local-db"
else
echo -e "${CYAN}[DB]${NC} 使用远程 PostgreSQL: $DB_HOST"
PROFILE_ARG=""
fi
# 启动服务(启用 BuildKit 缓存 + 并行构建加速)
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
export BUILDKIT_INLINE_CACHE=1
# 使用指定的 compose 文件
COMPOSE_ARGS="-f ${COMPOSE_FILE} ${PROFILE_ARG}"
SERVICES="$(${COMPOSE_CMD} ${COMPOSE_ARGS} config --services)"
service_exists() {
echo "$SERVICES" | grep -qx "$1"
}
BACKEND_SERVICES=()
for s in redis server agent; do
if service_exists "$s"; then
BACKEND_SERVICES+=("$s")
fi
done
# 如果使用本地数据库,先启动 postgres 并等待健康
start_postgres_first() {
if [ -n "$PROFILE_ARG" ]; then
echo -e "${CYAN}[DB]${NC} 启动 PostgreSQL 容器..."
${COMPOSE_CMD} ${COMPOSE_ARGS} up -d postgres
echo -e "${CYAN}[DB]${NC} 等待 PostgreSQL 就绪..."
local max_wait=30
local count=0
while [ $count -lt $max_wait ]; do
if ${COMPOSE_CMD} ${COMPOSE_ARGS} exec -T postgres pg_isready -U postgres >/dev/null 2>&1; then
echo -e "${GREEN}[DB]${NC} PostgreSQL 已就绪"
return 0
fi
sleep 1
count=$((count + 1))
done
echo -e "${YELLOW}[WARN]${NC} PostgreSQL 等待超时,继续启动其他服务..."
fi
}
2025-12-12 18:04:57 +08:00
echo ""
if [ "$DEV_MODE" = true ]; then
# 开发模式:本地构建
if [ "$WITH_FRONTEND" = true ]; then
echo -e "${CYAN}[BUILD]${NC} 并行构建镜像..."
${COMPOSE_CMD} ${COMPOSE_ARGS} build --parallel
start_postgres_first
2025-12-12 18:04:57 +08:00
echo -e "${CYAN}[START]${NC} 启动全部服务..."
${COMPOSE_CMD} ${COMPOSE_ARGS} up -d
else
echo -e "${CYAN}[BUILD]${NC} 并行构建后端镜像..."
${COMPOSE_CMD} ${COMPOSE_ARGS} build --parallel "${BACKEND_SERVICES[@]}"
start_postgres_first
2025-12-12 18:04:57 +08:00
echo -e "${CYAN}[START]${NC} 启动后端服务..."
${COMPOSE_CMD} ${COMPOSE_ARGS} up -d "${BACKEND_SERVICES[@]}"
2025-12-12 18:04:57 +08:00
fi
else
# 生产模式:拉取 Docker Hub 镜像
2025-12-19 19:48:01 +08:00
# pull 后 up -d 会自动检测镜像变化并重建容器
2025-12-12 18:04:57 +08:00
if [ "$WITH_FRONTEND" = true ]; then
echo -e "${CYAN}[PULL]${NC} 拉取最新镜像..."
${COMPOSE_CMD} ${COMPOSE_ARGS} pull
start_postgres_first
2025-12-12 18:04:57 +08:00
echo -e "${CYAN}[START]${NC} 启动全部服务..."
${COMPOSE_CMD} ${COMPOSE_ARGS} up -d
else
echo -e "${CYAN}[PULL]${NC} 拉取后端镜像..."
${COMPOSE_CMD} ${COMPOSE_ARGS} pull "${BACKEND_SERVICES[@]}"
start_postgres_first
2025-12-12 18:04:57 +08:00
echo -e "${CYAN}[START]${NC} 启动后端服务..."
${COMPOSE_CMD} ${COMPOSE_ARGS} up -d "${BACKEND_SERVICES[@]}"
2025-12-12 18:04:57 +08:00
fi
fi
echo -e "${GREEN}[OK]${NC} 服务已启动"
# 数据初始化
if [ "$DEV_MODE" = true ]; then
./scripts/init-data.sh --dev
else
./scripts/init-data.sh
fi
2025-12-12 18:04:57 +08:00
# 静默模式下不显示结果(由调用方显示)
if [ "$QUIET_MODE" = true ]; then
exit 0
fi
2025-12-12 18:04:57 +08:00
# 获取访问地址
PUBLIC_HOST=$(grep "^PUBLIC_HOST=" .env 2>/dev/null | cut -d= -f2)
if [ -n "$PUBLIC_HOST" ] && [ "$PUBLIC_HOST" != "server" ]; then
ACCESS_HOST="$PUBLIC_HOST"
else
ACCESS_HOST="localhost"
fi
# 显示结果
echo ""
echo -e "${BOLD}${GREEN}════════════════════════════════════════${NC}"
echo -e "${BOLD}${GREEN} 服务启动成功!${NC}"
echo -e "${BOLD}${GREEN}════════════════════════════════════════${NC}"
echo ""
echo -e "${BOLD}访问地址${NC}"
if [ "$WITH_FRONTEND" = true ]; then
echo -e " XingRin: ${CYAN}https://${ACCESS_HOST}:8083/${NC}"
2025-12-12 18:04:57 +08:00
echo -e " ${YELLOW}(HTTP 会自动跳转到 HTTPS)${NC}"
else
2025-12-19 18:37:05 +08:00
echo -e " API: ${CYAN}通过前端或 nginx 访问(后端未暴露 8888${NC}"
2025-12-12 18:04:57 +08:00
echo ""
echo -e "${YELLOW}[TIP]${NC} 前端未启动,请手动运行:"
echo " cd frontend && pnpm dev"
fi
echo ""
echo -e "${BOLD}默认账号${NC}"
echo " 用户名: admin"
echo " 密码: admin"
echo -e " ${YELLOW}[!] 请首次登录后修改密码${NC}"
echo ""