#!/usr/bin/env bash set -euo pipefail if [[ "$(id -u)" -ne 0 ]]; then echo "请使用 root 执行此脚本" exit 1 fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" CONFIG_FILE="${SCRIPT_DIR}/install_overseas_quick.conf" CONFIG_EXAMPLE="${SCRIPT_DIR}/install_overseas_quick.conf.example" if [[ ! -f "${CONFIG_FILE}" ]]; then echo "未找到配置文件:${CONFIG_FILE}" echo "请先执行:cp ${CONFIG_EXAMPLE} ${CONFIG_FILE}" exit 1 fi # shellcheck disable=SC1090 source "${CONFIG_FILE}" : "${API_DOMAIN:=api.domain.com}" : "${ADMIN_DOMAIN:=admin.domain}" : "${DB_NAME:=domain}" : "${DB_USER:=domainuser}" : "${DB_PASSWORD:=CHANGE_ME_DB_PASSWORD}" : "${OVERSEAS_NODE_CODE:=overseas-control-01}" : "${NODE_VERSION:=20}" : "${NODE_NVM_DIR:=}" WORKSPACE_ROOT="/www/wwwroot" REPO_DIR="${WORKSPACE_ROOT}/getDomain" BASE_DIR="/opt/domaincheck" DOMAINCHECK_DIR="${BASE_DIR}/domainCheck" DOMAIN_API_DIR="${BASE_DIR}/domain-api" DOMAIN_WEB_DIR="${BASE_DIR}/domain-web" if [[ "${DB_PASSWORD}" == "CHANGE_ME_DB_PASSWORD" ]]; then echo "请先修改配置文件中的必填项:DB_PASSWORD" exit 1 fi mkdir -p "${WORKSPACE_ROOT}" if [[ ! -d "${REPO_DIR}/.git" ]]; then echo "未找到仓库目录:${REPO_DIR}" echo "全新机器首次部署,必须先手动执行 git clone,把仓库拉到 /www/wwwroot/getDomain" exit 1 fi echo "已检测到仓库目录:${REPO_DIR}" echo "当前脚本不会执行任何 Git 命令。" echo "如需更新代码,请先手动切到仓库属主完成 git pull,再重新执行本脚本。" mkdir -p "${BASE_DIR}" ln -sfn "${REPO_DIR}/domain-api" "${DOMAIN_API_DIR}" ln -sfn "${REPO_DIR}/domain-web" "${DOMAIN_WEB_DIR}" ln -sfn "${REPO_DIR}/domainCheck" "${DOMAINCHECK_DIR}" cd "${DOMAINCHECK_DIR}" python3.11 -m venv .venv || true source .venv/bin/activate pip install --upgrade pip python3.11 - <<'PY' from pathlib import Path source = Path("requirements.txt") target = Path("requirements.linux.txt") raw = source.read_bytes() for encoding in ("utf-8", "utf-16", "utf-16-le", "utf-16-be", "gbk"): try: text = raw.decode(encoding) break except UnicodeDecodeError: continue else: raise SystemExit("无法解析 requirements.txt 编码") skip_prefixes = ( "pywin32==", "pywin32-ctypes==", "twisted-iocpsupport==", "win32-setctime==", ) lines = [] for line in text.splitlines(): normalized = line.strip().lstrip("\ufeff") if normalized.lower().startswith(skip_prefixes): continue lines.append(normalized) target.write_text("\n".join(lines) + "\n", encoding="utf-8") PY pip install -r requirements.linux.txt "${DOMAINCHECK_DIR}/.venv/bin/pip" install fastapi uvicorn pydantic-settings psycopg2-binary redis openpyxl python-multipart cat >"${DOMAINCHECK_DIR}/.env" <"${DOMAIN_WEB_DIR}/.env.production" </dev/null 2>&1 && command -v npm >/dev/null 2>&1; then echo "未检测到 nvm,改用系统已安装的 node/npm" echo "当前 node 版本:$(node -v)" NODE_READY=true fi if [[ "${NODE_READY}" != "true" ]]; then echo "未找到可用的 Node 运行环境。" echo "请执行以下任一方案后重试:" echo "1. 用 root 安装 nvm,并确保 /root/.nvm/nvm.sh 存在" echo "2. 在 install_overseas_quick.conf 中填写 NODE_NVM_DIR,例如:/home/www/.nvm" echo "3. 预先安装系统全局 node 和 npm" exit 1 fi npm install npm run build cp "${DOMAIN_API_DIR}/deploy/multi-region/templates/domaincheck-api.env.example" /etc/default/domaincheck-api sed -i "s#^DOMAIN_ROOT=.*#DOMAIN_ROOT=${DOMAINCHECK_DIR}#" /etc/default/domaincheck-api sed -i 's#^API_HOST=.*#API_HOST=0.0.0.0#' /etc/default/domaincheck-api sed -i 's#^API_PORT=.*#API_PORT=8100#' /etc/default/domaincheck-api sed -i "s#^NODE_CODE=.*#NODE_CODE=${OVERSEAS_NODE_CODE}#" /etc/default/domaincheck-api sed -i 's#^NODE_REGION=.*#NODE_REGION=overseas#' /etc/default/domaincheck-api sed -i 's#^NODE_ROLE=.*#NODE_ROLE=control#' /etc/default/domaincheck-api sed -i 's#^SYNC_PUSH_ENABLED=.*#SYNC_PUSH_ENABLED=false#' /etc/default/domaincheck-api sed -i "s#^CORS_ORIGINS=.*#CORS_ORIGINS=https://${ADMIN_DOMAIN},http://127.0.0.1:3201,http://localhost:3201#" /etc/default/domaincheck-api cp "${DOMAIN_API_DIR}/deploy/systemd/domain-api.service" /etc/systemd/system/domaincheck-api.service cp "${DOMAIN_API_DIR}/deploy/systemd/domain-worker.service" /etc/systemd/system/domaincheck-worker.service mkdir -p "${DOMAIN_API_DIR}/runtime" touch "${DOMAINCHECK_DIR}/detect_worker.log" chown -R www:www "${DOMAIN_API_DIR}/runtime" chown www:www "${DOMAINCHECK_DIR}/detect_worker.log" chmod 664 "${DOMAINCHECK_DIR}/detect_worker.log" systemctl daemon-reload systemctl enable domaincheck-api systemctl enable domaincheck-worker systemctl restart domaincheck-api systemctl restart domaincheck-worker chown -R www:www "${REPO_DIR}" echo echo "国外主控机部署完成,建议继续执行:" echo "curl http://127.0.0.1:8100/health" echo "curl http://127.0.0.1:8100/api/v1/runtime/preflight" echo "curl http://127.0.0.1:8100/api/v1/runtime/readiness"