You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
5.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
# 查价中台 — 生产环境一键部署Linux
# 用法:
# cp deploy/.env.production.example .env # 编辑必填项
# bash deploy/install.sh
# bash deploy/install.sh --nginx-http # 额外安装 Nginx HTTP 反代
# bash deploy/install.sh --nginx-ssl # 额外安装 Nginx HTTPS 反代(需已有证书)
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
COMPOSE_FILE="${ROOT_DIR}/deploy/docker-compose.yml"
ENV_FILE="${ROOT_DIR}/.env"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() { echo -e "${GREEN}[deploy]${NC} $*"; }
warn() { echo -e "${YELLOW}[deploy]${NC} $*"; }
err() { echo -e "${RED}[deploy]${NC} $*" >&2; }
require_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
err "缺少命令: $1"
exit 1
fi
}
validate_env() {
if [[ ! -f "$ENV_FILE" ]]; then
err "未找到 .env请先执行cp deploy/.env.production.example .env"
exit 1
fi
# shellcheck disable=SC1090
set -a
source "$ENV_FILE"
set +a
local missing=0
for key in MYSQL_ROOT_PASSWORD JWT_SECRET HOST_SERVICE_TOKENS CUSTOMER_REGISTRY; do
local val="${!key:-}"
if [[ -z "$val" ]] || [[ "$val" == CHANGE_ME* ]]; then
err "请在 .env 中填写: $key(当前仍为占位符)"
missing=1
fi
done
if [[ "${RPA_MOCK_MODE:-false}" == "true" ]]; then
warn "RPA_MOCK_MODE=true 仅用于测试,生产环境请设为 false"
fi
if [[ -z "${MOTHERSHIP_QUOTE_URLS:-}" ]]; then
err "请在 .env 中填写 MOTHERSHIP_QUOTE_URLS"
missing=1
fi
if [[ $missing -ne 0 ]]; then
exit 1
fi
}
install_nginx() {
local mode="$1"
local template=""
local domain="${PUBLIC_DOMAIN:-quote.example.com}"
if [[ "$mode" == "http" ]]; then
template="${ROOT_DIR}/deploy/nginx/chajia.http.conf"
elif [[ "$mode" == "ssl" ]]; then
template="${ROOT_DIR}/deploy/nginx/chajia.ssl.conf"
else
err "未知 nginx 模式: $mode"
exit 1
fi
require_cmd nginx
local tmp="/tmp/chajia-nginx-$$.conf"
sed "s/quote\.example\.com/${domain}/g" "$template" > "$tmp"
if [[ -d /etc/nginx/sites-available ]]; then
sudo cp "$tmp" /etc/nginx/sites-available/chajia
sudo ln -sf /etc/nginx/sites-available/chajia /etc/nginx/sites-enabled/chajia
sudo rm -f /etc/nginx/sites-enabled/default 2>/dev/null || true
elif [[ -d /etc/nginx/conf.d ]]; then
sudo cp "$tmp" /etc/nginx/conf.d/chajia.conf
else
err "未找到 /etc/nginx/sites-available 或 /etc/nginx/conf.d"
rm -f "$tmp"
exit 1
fi
rm -f "$tmp"
sudo nginx -t
sudo systemctl reload nginx
log "Nginx 已配置(${mode}),域名: ${domain}"
}
deploy_docker() {
require_cmd docker
if ! docker compose version >/dev/null 2>&1; then
err "需要 Docker Compose V2docker compose"
exit 1
fi
cd "$ROOT_DIR"
log "构建并启动容器..."
docker compose -f "$COMPOSE_FILE" up -d --build
log "等待 MySQL 就绪..."
sleep 5
log "执行数据库迁移..."
docker compose -f "$COMPOSE_FILE" run --rm --no-deps rpa-worker npx prisma migrate deploy
log "初始化种子数据(管理员账号)..."
docker compose -f "$COMPOSE_FILE" run --rm --no-deps rpa-worker npx tsx prisma/seed.ts 2>/dev/null \
|| warn "seed 已存在或跳过(默认账号 admin_demo / Demo@123"
log "容器状态:"
docker compose -f "$COMPOSE_FILE" ps
}
smoke_check() {
local port="${APP_PORT:-3000}"
local url="http://127.0.0.1:${port}"
log "健康检查: ${url}"
if curl -sf -o /dev/null -w "%{http_code}" "$url" | grep -qE '200|307|308'; then
log "Web 服务响应正常"
else
warn "Web 暂未响应,请稍后执行: docker compose -f deploy/docker-compose.yml logs -f next-app"
fi
}
print_summary() {
local port="${APP_PORT:-3000}"
local domain="${PUBLIC_DOMAIN:-quote.example.com}"
echo ""
log "========== 部署完成 =========="
echo " 本地访问: http://127.0.0.1:${port}"
echo " 对外域名: https://${domain} (需配置 Nginx + 证书)"
echo " 管理端: /admin/alerts (账号见 prisma seed: admin_demo / Demo@123请尽快改密"
echo ""
echo " 外部系统 API"
echo " POST /api/addresses/mothership-candidates"
echo " POST /api/quotes"
echo " GET /api/quotes/{quote_id}"
echo ""
echo " 常用命令:"
echo " docker compose -f deploy/docker-compose.yml logs -f rpa-worker"
echo " docker compose -f deploy/docker-compose.yml restart"
echo " docker compose -f deploy/docker-compose.yml down"
echo ""
warn "【人工必做】见 deploy/README.md「部署后检查清单」"
}
main() {
local nginx_mode=""
for arg in "$@"; do
case "$arg" in
--nginx-http) nginx_mode="http" ;;
--nginx-ssl) nginx_mode="ssl" ;;
--help|-h)
echo "用法: bash deploy/install.sh [--nginx-http|--nginx-ssl]"
exit 0
;;
esac
done
validate_env
deploy_docker
smoke_check
if [[ -n "$nginx_mode" ]]; then
install_nginx "$nginx_mode"
else
warn "未安装 Nginx。公网访问请执行: bash deploy/install.sh --nginx-http"
fi
print_summary
}
main "$@"