PMFlow/devops/tunnel/start.sh

136 lines
3.9 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
set -euo pipefail
# PMFlow 公网穿透启动器(保留为唯一 tunnel 入口)
# 优先命名隧道;未配置时自动退回 quick tunnel。
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd -- "${SCRIPT_DIR}/../.." && pwd)"
CONFIG_FILE="${SCRIPT_DIR}/config.yml"
SETUP_SCRIPT="${SCRIPT_DIR}/setup.sh"
LOG_DIR="${ROOT_DIR}/logs"
FRONTEND_PORT="${PMFLOW_TUNNEL_FRONTEND_PORT:-${FRONTEND_PORT:-5174}}"
BACKEND_PORT="${PMFLOW_TUNNEL_BACKEND_PORT:-${BACKEND_PORT:-8000}}"
TUNNEL_PROTOCOL="${PMFLOW_TUNNEL_PROTOCOL:-quic}"
HEALTH_RETRIES="${PMFLOW_TUNNEL_HEALTH_RETRIES:-3}"
FOREGROUND="${PMFLOW_TUNNEL_FOREGROUND:-1}"
FRONT_LOG="${LOG_DIR}/tunnel-frontend.log"
BACK_LOG="${LOG_DIR}/tunnel-backend.log"
extract_url() {
local logfile="$1"
grep -aEo 'https://[-a-z0-9]+\.trycloudflare\.com' "$logfile" 2>/dev/null | tail -1
}
wait_for_url() {
local logfile="$1"
local retries="${2:-30}"
local i=1
local url=""
while [ "$i" -le "$retries" ]; do
url="$(extract_url "$logfile")"
if [ -n "$url" ]; then
echo "$url"
return 0
fi
sleep 1
i=$((i + 1))
done
return 1
}
check_url() {
local url="$1"
local max_retry="$2"
local retry=1
while [ "$retry" -le "$max_retry" ]; do
if curl -kfsS --max-time 8 "$url" >/dev/null 2>&1; then
return 0
fi
sleep 2
retry=$((retry + 1))
done
return 1
}
run_quick_tunnels() {
mkdir -p "$LOG_DIR"
pkill -f "cloudflared tunnel .*127\\.0\\.0\\.1:${FRONTEND_PORT}" >/dev/null 2>&1 || true
pkill -f "cloudflared tunnel .*127\\.0\\.0\\.1:${BACKEND_PORT}" >/dev/null 2>&1 || true
echo "🚀 启动临时隧道..."
echo "📂 日志目录: ${LOG_DIR}"
echo "🌐 前端隧道: 127.0.0.1:${FRONTEND_PORT}"
cloudflared tunnel --protocol "${TUNNEL_PROTOCOL}" --url "http://127.0.0.1:${FRONTEND_PORT}" >"$FRONT_LOG" 2>&1 &
local front_pid=$!
echo "🌐 后端隧道: 127.0.0.1:${BACKEND_PORT}"
cloudflared tunnel --protocol "${TUNNEL_PROTOCOL}" --url "http://127.0.0.1:${BACKEND_PORT}" >"$BACK_LOG" 2>&1 &
local back_pid=$!
echo "⏳ 等待隧道地址..."
local front_url=""
local back_url=""
front_url="$(wait_for_url "$FRONT_LOG" 45 || true)"
back_url="$(wait_for_url "$BACK_LOG" 45 || true)"
if [ -z "$front_url" ] || [ -z "$back_url" ]; then
echo "❌ 未获取到公网地址。"
echo " 前端日志: $FRONT_LOG"
echo " 后端日志: $BACK_LOG"
tail -n 20 "$FRONT_LOG" || true
tail -n 20 "$BACK_LOG" || true
kill "$front_pid" "$back_pid" >/dev/null 2>&1 || true
return 1
fi
local front_ok=false
local back_ok=false
if check_url "${front_url}/login" "$HEALTH_RETRIES" || check_url "${front_url}" "$HEALTH_RETRIES"; then
front_ok=true
fi
if check_url "${back_url}/healthz" "$HEALTH_RETRIES"; then
back_ok=true
fi
if [ "$front_ok" = true ] && [ "$back_ok" = true ]; then
echo "✅ 隧道连通成功"
else
echo "⚠️ 隧道已启动,但健康检查未全部通过(可稍后重试)"
fi
echo "----------------------------------------"
echo "前端: ${front_url}"
echo "后端: ${back_url}"
echo "----------------------------------------"
echo "ℹ️ 停止命令: pkill -f \"cloudflared tunnel\""
if [ "$FOREGROUND" != "1" ]; then
echo "✅ 已切到后台运行"
echo " 前端 PID: ${front_pid}"
echo " 后端 PID: ${back_pid}"
return 0
fi
cleanup() {
echo ""
echo "🔴 tunnel 已关闭"
kill "$front_pid" "$back_pid" >/dev/null 2>&1 || true
}
trap cleanup EXIT INT TERM
wait "$front_pid" "$back_pid"
}
echo "🚀 启动公网穿透..."
if [ -f "$CONFIG_FILE" ]; then
echo "✅ 检测到命名隧道配置: ${CONFIG_FILE}"
echo "🌐 使用命名隧道运行(前台)"
exec cloudflared tunnel run --config "$CONFIG_FILE"
fi
echo "⚠️ 未检测到命名隧道配置,自动切换临时隧道。"
echo " 若需固定域名,请先执行: ${SETUP_SCRIPT}"
run_quick_tunnels