mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-08 18:56:37 +08:00
+93
-51
@@ -11,6 +11,7 @@ export LC_ALL=C
|
|||||||
DOCKER_COMPOSEV4_URL="https://raw.githubusercontent.com/bqlpfy/flux-panel/refs/heads/main/docker-compose-v4.yml"
|
DOCKER_COMPOSEV4_URL="https://raw.githubusercontent.com/bqlpfy/flux-panel/refs/heads/main/docker-compose-v4.yml"
|
||||||
DOCKER_COMPOSEV6_URL="https://raw.githubusercontent.com/bqlpfy/flux-panel/refs/heads/main/docker-compose-v6.yml"
|
DOCKER_COMPOSEV6_URL="https://raw.githubusercontent.com/bqlpfy/flux-panel/refs/heads/main/docker-compose-v6.yml"
|
||||||
GOST_SQL_URL="https://raw.githubusercontent.com/bqlpfy/flux-panel/refs/heads/main/gost.sql"
|
GOST_SQL_URL="https://raw.githubusercontent.com/bqlpfy/flux-panel/refs/heads/main/gost.sql"
|
||||||
|
PROXY_SH_URL="https://raw.githubusercontent.com/bqlpfy/flux-panel/refs/heads/main/proxy.sh"
|
||||||
|
|
||||||
COUNTRY=$(curl -s https://ipinfo.io/country)
|
COUNTRY=$(curl -s https://ipinfo.io/country)
|
||||||
if [ "$COUNTRY" = "CN" ]; then
|
if [ "$COUNTRY" = "CN" ]; then
|
||||||
@@ -18,6 +19,8 @@ if [ "$COUNTRY" = "CN" ]; then
|
|||||||
DOCKER_COMPOSEV4_URL="https://ghfast.top/${DOCKER_COMPOSEV4_URL}"
|
DOCKER_COMPOSEV4_URL="https://ghfast.top/${DOCKER_COMPOSEV4_URL}"
|
||||||
DOCKER_COMPOSEV6_URL="https://ghfast.top/${DOCKER_COMPOSEV6_URL}"
|
DOCKER_COMPOSEV6_URL="https://ghfast.top/${DOCKER_COMPOSEV6_URL}"
|
||||||
GOST_SQL_URL="https://ghfast.top/${GOST_SQL_URL}"
|
GOST_SQL_URL="https://ghfast.top/${GOST_SQL_URL}"
|
||||||
|
|
||||||
|
PROXY_SH_URL="https://ghfast.top/${PROXY_SH_URL}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
@@ -52,7 +55,7 @@ check_docker() {
|
|||||||
# 检测系统是否支持 IPv6
|
# 检测系统是否支持 IPv6
|
||||||
check_ipv6_support() {
|
check_ipv6_support() {
|
||||||
echo "🔍 检测 IPv6 支持..."
|
echo "🔍 检测 IPv6 支持..."
|
||||||
|
|
||||||
# 检查是否有 IPv6 地址(排除 link-local 地址)
|
# 检查是否有 IPv6 地址(排除 link-local 地址)
|
||||||
if ip -6 addr show | grep -v "scope link" | grep -q "inet6"; then
|
if ip -6 addr show | grep -v "scope link" | grep -q "inet6"; then
|
||||||
echo "✅ 检测到系统支持 IPv6"
|
echo "✅ 检测到系统支持 IPv6"
|
||||||
@@ -71,26 +74,26 @@ check_ipv6_support() {
|
|||||||
# 配置 Docker 启用 IPv6
|
# 配置 Docker 启用 IPv6
|
||||||
configure_docker_ipv6() {
|
configure_docker_ipv6() {
|
||||||
echo "🔧 配置 Docker IPv6 支持..."
|
echo "🔧 配置 Docker IPv6 支持..."
|
||||||
|
|
||||||
# 检查操作系统类型
|
# 检查操作系统类型
|
||||||
OS_TYPE=$(uname -s)
|
OS_TYPE=$(uname -s)
|
||||||
|
|
||||||
if [[ "$OS_TYPE" == "Darwin" ]]; then
|
if [[ "$OS_TYPE" == "Darwin" ]]; then
|
||||||
# macOS 上 Docker Desktop 已默认支持 IPv6
|
# macOS 上 Docker Desktop 已默认支持 IPv6
|
||||||
echo "✅ macOS Docker Desktop 默认支持 IPv6"
|
echo "✅ macOS Docker Desktop 默认支持 IPv6"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Docker daemon 配置文件路径
|
# Docker daemon 配置文件路径
|
||||||
DOCKER_CONFIG="/etc/docker/daemon.json"
|
DOCKER_CONFIG="/etc/docker/daemon.json"
|
||||||
|
|
||||||
# 检查是否需要 sudo
|
# 检查是否需要 sudo
|
||||||
if [[ $EUID -ne 0 ]]; then
|
if [[ $EUID -ne 0 ]]; then
|
||||||
SUDO_CMD="sudo"
|
SUDO_CMD="sudo"
|
||||||
else
|
else
|
||||||
SUDO_CMD=""
|
SUDO_CMD=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 检查 Docker 配置文件
|
# 检查 Docker 配置文件
|
||||||
if [ -f "$DOCKER_CONFIG" ]; then
|
if [ -f "$DOCKER_CONFIG" ]; then
|
||||||
# 检查是否已经配置了 IPv6
|
# 检查是否已经配置了 IPv6
|
||||||
@@ -100,7 +103,7 @@ configure_docker_ipv6() {
|
|||||||
echo "📝 更新 Docker 配置以启用 IPv6..."
|
echo "📝 更新 Docker 配置以启用 IPv6..."
|
||||||
# 备份原配置
|
# 备份原配置
|
||||||
$SUDO_CMD cp "$DOCKER_CONFIG" "${DOCKER_CONFIG}.backup"
|
$SUDO_CMD cp "$DOCKER_CONFIG" "${DOCKER_CONFIG}.backup"
|
||||||
|
|
||||||
# 使用 jq 或 sed 添加 IPv6 配置
|
# 使用 jq 或 sed 添加 IPv6 配置
|
||||||
if command -v jq &> /dev/null; then
|
if command -v jq &> /dev/null; then
|
||||||
$SUDO_CMD jq '. + {"ipv6": true, "fixed-cidr-v6": "fd00::/80"}' "$DOCKER_CONFIG" > /tmp/daemon.json && $SUDO_CMD mv /tmp/daemon.json "$DOCKER_CONFIG"
|
$SUDO_CMD jq '. + {"ipv6": true, "fixed-cidr-v6": "fd00::/80"}' "$DOCKER_CONFIG" > /tmp/daemon.json && $SUDO_CMD mv /tmp/daemon.json "$DOCKER_CONFIG"
|
||||||
@@ -108,7 +111,7 @@ configure_docker_ipv6() {
|
|||||||
# 如果没有 jq,使用 sed
|
# 如果没有 jq,使用 sed
|
||||||
$SUDO_CMD sed -i 's/^{$/{\n "ipv6": true,\n "fixed-cidr-v6": "fd00::\/80",/' "$DOCKER_CONFIG"
|
$SUDO_CMD sed -i 's/^{$/{\n "ipv6": true,\n "fixed-cidr-v6": "fd00::\/80",/' "$DOCKER_CONFIG"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "🔄 重启 Docker 服务..."
|
echo "🔄 重启 Docker 服务..."
|
||||||
if command -v systemctl &> /dev/null; then
|
if command -v systemctl &> /dev/null; then
|
||||||
$SUDO_CMD systemctl restart docker
|
$SUDO_CMD systemctl restart docker
|
||||||
@@ -127,7 +130,7 @@ configure_docker_ipv6() {
|
|||||||
"ipv6": true,
|
"ipv6": true,
|
||||||
"fixed-cidr-v6": "fd00::/80"
|
"fixed-cidr-v6": "fd00::/80"
|
||||||
}' | $SUDO_CMD tee "$DOCKER_CONFIG" > /dev/null
|
}' | $SUDO_CMD tee "$DOCKER_CONFIG" > /dev/null
|
||||||
|
|
||||||
echo "🔄 重启 Docker 服务..."
|
echo "🔄 重启 Docker 服务..."
|
||||||
if command -v systemctl &> /dev/null; then
|
if command -v systemctl &> /dev/null; then
|
||||||
$SUDO_CMD systemctl restart docker
|
$SUDO_CMD systemctl restart docker
|
||||||
@@ -150,7 +153,8 @@ show_menu() {
|
|||||||
echo "2. 更新面板"
|
echo "2. 更新面板"
|
||||||
echo "3. 卸载面板"
|
echo "3. 卸载面板"
|
||||||
echo "4. 导出备份"
|
echo "4. 导出备份"
|
||||||
echo "5. 退出"
|
echo "5. 安装并配置反向代理(Caddy)"
|
||||||
|
echo "6. 退出"
|
||||||
echo "==============================================="
|
echo "==============================================="
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,12 +196,12 @@ install_panel() {
|
|||||||
echo "🚀 开始安装面板..."
|
echo "🚀 开始安装面板..."
|
||||||
check_docker
|
check_docker
|
||||||
get_config_params
|
get_config_params
|
||||||
|
|
||||||
echo "🔽 下载必要文件..."
|
echo "🔽 下载必要文件..."
|
||||||
DOCKER_COMPOSE_URL=$(get_docker_compose_url)
|
DOCKER_COMPOSE_URL=$(get_docker_compose_url)
|
||||||
echo "📡 选择配置文件:$(basename "$DOCKER_COMPOSE_URL")"
|
echo "📡 选择配置文件:$(basename "$DOCKER_COMPOSE_URL")"
|
||||||
curl -L -o docker-compose.yml "$DOCKER_COMPOSE_URL"
|
curl -L -o docker-compose.yml "$DOCKER_COMPOSE_URL"
|
||||||
|
|
||||||
# 检查 gost.sql 是否已存在
|
# 检查 gost.sql 是否已存在
|
||||||
if [[ -f "gost.sql" ]]; then
|
if [[ -f "gost.sql" ]]; then
|
||||||
echo "⏭️ 跳过下载: gost.sql (使用当前位置的文件)"
|
echo "⏭️ 跳过下载: gost.sql (使用当前位置的文件)"
|
||||||
@@ -231,7 +235,7 @@ EOF
|
|||||||
echo "📚 文档地址: https://tes.cc/guide.html"
|
echo "📚 文档地址: https://tes.cc/guide.html"
|
||||||
echo "💡 默认管理员账号: admin_user / admin_user"
|
echo "💡 默认管理员账号: admin_user / admin_user"
|
||||||
echo "⚠️ 登录后请立即修改默认密码!"
|
echo "⚠️ 登录后请立即修改默认密码!"
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +243,7 @@ EOF
|
|||||||
update_panel() {
|
update_panel() {
|
||||||
echo "🔄 开始更新面板..."
|
echo "🔄 开始更新面板..."
|
||||||
check_docker
|
check_docker
|
||||||
|
|
||||||
echo "🔽 下载最新配置文件..."
|
echo "🔽 下载最新配置文件..."
|
||||||
DOCKER_COMPOSE_URL=$(get_docker_compose_url)
|
DOCKER_COMPOSE_URL=$(get_docker_compose_url)
|
||||||
echo "📡 选择配置文件:$(basename "$DOCKER_COMPOSE_URL")"
|
echo "📡 选择配置文件:$(basename "$DOCKER_COMPOSE_URL")"
|
||||||
@@ -254,16 +258,16 @@ update_panel() {
|
|||||||
|
|
||||||
echo "🛑 停止当前服务..."
|
echo "🛑 停止当前服务..."
|
||||||
$DOCKER_CMD down
|
$DOCKER_CMD down
|
||||||
|
|
||||||
echo "⬇️ 拉取最新镜像..."
|
echo "⬇️ 拉取最新镜像..."
|
||||||
$DOCKER_CMD pull
|
$DOCKER_CMD pull
|
||||||
|
|
||||||
echo "🚀 启动更新后的服务..."
|
echo "🚀 启动更新后的服务..."
|
||||||
$DOCKER_CMD up -d
|
$DOCKER_CMD up -d
|
||||||
|
|
||||||
# 等待服务启动
|
# 等待服务启动
|
||||||
echo "⏳ 等待服务启动..."
|
echo "⏳ 等待服务启动..."
|
||||||
|
|
||||||
# 检查后端容器健康状态
|
# 检查后端容器健康状态
|
||||||
echo "🔍 检查后端服务状态..."
|
echo "🔍 检查后端服务状态..."
|
||||||
for i in {1..90}; do
|
for i in {1..90}; do
|
||||||
@@ -294,7 +298,7 @@ update_panel() {
|
|||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
# 检查数据库容器健康状态
|
# 检查数据库容器健康状态
|
||||||
echo "🔍 检查数据库服务状态..."
|
echo "🔍 检查数据库服务状态..."
|
||||||
for i in {1..60}; do
|
for i in {1..60}; do
|
||||||
@@ -325,14 +329,14 @@ update_panel() {
|
|||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
# 从容器环境变量获取数据库信息
|
# 从容器环境变量获取数据库信息
|
||||||
echo "🔍 获取数据库配置信息..."
|
echo "🔍 获取数据库配置信息..."
|
||||||
|
|
||||||
# 等待一下让服务完全就绪
|
# 等待一下让服务完全就绪
|
||||||
echo "⏳ 等待服务完全就绪..."
|
echo "⏳ 等待服务完全就绪..."
|
||||||
sleep 5
|
sleep 5
|
||||||
|
|
||||||
# 先检查后端容器是否在运行
|
# 先检查后端容器是否在运行
|
||||||
if ! docker ps --format "{{.Names}}" | grep -q "^springboot-backend$"; then
|
if ! docker ps --format "{{.Names}}" | grep -q "^springboot-backend$"; then
|
||||||
echo "❌ 后端容器未运行,无法获取数据库配置"
|
echo "❌ 后端容器未运行,无法获取数据库配置"
|
||||||
@@ -341,15 +345,15 @@ update_panel() {
|
|||||||
echo "🛑 更新终止"
|
echo "🛑 更新终止"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DB_INFO=$(docker exec springboot-backend env | grep "^DB_" 2>/dev/null || echo "")
|
DB_INFO=$(docker exec springboot-backend env | grep "^DB_" 2>/dev/null || echo "")
|
||||||
|
|
||||||
if [[ -n "$DB_INFO" ]]; then
|
if [[ -n "$DB_INFO" ]]; then
|
||||||
DB_NAME=$(echo "$DB_INFO" | grep "^DB_NAME=" | cut -d'=' -f2)
|
DB_NAME=$(echo "$DB_INFO" | grep "^DB_NAME=" | cut -d'=' -f2)
|
||||||
DB_PASSWORD=$(echo "$DB_INFO" | grep "^DB_PASSWORD=" | cut -d'=' -f2)
|
DB_PASSWORD=$(echo "$DB_INFO" | grep "^DB_PASSWORD=" | cut -d'=' -f2)
|
||||||
DB_USER=$(echo "$DB_INFO" | grep "^DB_USER=" | cut -d'=' -f2)
|
DB_USER=$(echo "$DB_INFO" | grep "^DB_USER=" | cut -d'=' -f2)
|
||||||
DB_HOST=$(echo "$DB_INFO" | grep "^DB_HOST=" | cut -d'=' -f2)
|
DB_HOST=$(echo "$DB_INFO" | grep "^DB_HOST=" | cut -d'=' -f2)
|
||||||
|
|
||||||
echo "📋 数据库配置:"
|
echo "📋 数据库配置:"
|
||||||
echo " 数据库名: $DB_NAME"
|
echo " 数据库名: $DB_NAME"
|
||||||
echo " 用户名: $DB_USER"
|
echo " 用户名: $DB_USER"
|
||||||
@@ -359,14 +363,14 @@ update_panel() {
|
|||||||
echo "🔍 尝试诊断问题:"
|
echo "🔍 尝试诊断问题:"
|
||||||
echo " 容器状态: $(docker inspect -f '{{.State.Status}}' springboot-backend 2>/dev/null || echo '容器不存在')"
|
echo " 容器状态: $(docker inspect -f '{{.State.Status}}' springboot-backend 2>/dev/null || echo '容器不存在')"
|
||||||
echo " 健康状态: $(docker inspect -f '{{.State.Health.Status}}' springboot-backend 2>/dev/null || echo '无健康检查')"
|
echo " 健康状态: $(docker inspect -f '{{.State.Health.Status}}' springboot-backend 2>/dev/null || echo '无健康检查')"
|
||||||
|
|
||||||
# 尝试从 .env 文件读取配置
|
# 尝试从 .env 文件读取配置
|
||||||
if [[ -f ".env" ]]; then
|
if [[ -f ".env" ]]; then
|
||||||
echo "🔄 尝试从 .env 文件读取配置..."
|
echo "🔄 尝试从 .env 文件读取配置..."
|
||||||
DB_NAME=$(grep "^DB_NAME=" .env | cut -d'=' -f2 2>/dev/null)
|
DB_NAME=$(grep "^DB_NAME=" .env | cut -d'=' -f2 2>/dev/null)
|
||||||
DB_PASSWORD=$(grep "^DB_PASSWORD=" .env | cut -d'=' -f2 2>/dev/null)
|
DB_PASSWORD=$(grep "^DB_PASSWORD=" .env | cut -d'=' -f2 2>/dev/null)
|
||||||
DB_USER=$(grep "^DB_USER=" .env | cut -d'=' -f2 2>/dev/null)
|
DB_USER=$(grep "^DB_USER=" .env | cut -d'=' -f2 2>/dev/null)
|
||||||
|
|
||||||
if [[ -n "$DB_NAME" && -n "$DB_PASSWORD" && -n "$DB_USER" ]]; then
|
if [[ -n "$DB_NAME" && -n "$DB_PASSWORD" && -n "$DB_USER" ]]; then
|
||||||
echo "✅ 从 .env 文件成功读取数据库配置"
|
echo "✅ 从 .env 文件成功读取数据库配置"
|
||||||
echo "📋 数据库配置:"
|
echo "📋 数据库配置:"
|
||||||
@@ -383,17 +387,17 @@ update_panel() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 检查必要的数据库配置
|
# 检查必要的数据库配置
|
||||||
if [[ -z "$DB_PASSWORD" || -z "$DB_USER" || -z "$DB_NAME" ]]; then
|
if [[ -z "$DB_PASSWORD" || -z "$DB_USER" || -z "$DB_NAME" ]]; then
|
||||||
echo "❌ 数据库配置不完整(缺少必要参数)"
|
echo "❌ 数据库配置不完整(缺少必要参数)"
|
||||||
echo "🛑 更新终止"
|
echo "🛑 更新终止"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 执行数据库字段变更
|
# 执行数据库字段变更
|
||||||
echo "🔄 执行数据库结构更新..."
|
echo "🔄 执行数据库结构更新..."
|
||||||
|
|
||||||
# 创建临时迁移文件(现在有了数据库信息)
|
# 创建临时迁移文件(现在有了数据库信息)
|
||||||
cat > temp_migration.sql <<EOF
|
cat > temp_migration.sql <<EOF
|
||||||
-- 数据库结构更新
|
-- 数据库结构更新
|
||||||
@@ -847,7 +851,7 @@ SET \`created_time\` = UNIX_TIMESTAMP() * 1000
|
|||||||
WHERE \`created_time\` = 0 OR \`created_time\` IS NULL;
|
WHERE \`created_time\` = 0 OR \`created_time\` IS NULL;
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# 检查数据库容器
|
# 检查数据库容器
|
||||||
if ! docker ps --format "{{.Names}}" | grep -q "^gost-mysql$"; then
|
if ! docker ps --format "{{.Names}}" | grep -q "^gost-mysql$"; then
|
||||||
echo "❌ 数据库容器 gost-mysql 未运行"
|
echo "❌ 数据库容器 gost-mysql 未运行"
|
||||||
@@ -857,7 +861,7 @@ EOF
|
|||||||
echo "📁 迁移文件已保存为 temp_migration.sql"
|
echo "📁 迁移文件已保存为 temp_migration.sql"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 执行数据库迁移
|
# 执行数据库迁移
|
||||||
if docker exec -i gost-mysql mysql -u "$DB_USER" -p"$DB_PASSWORD" < temp_migration.sql 2>/dev/null; then
|
if docker exec -i gost-mysql mysql -u "$DB_USER" -p"$DB_PASSWORD" < temp_migration.sql 2>/dev/null; then
|
||||||
echo "✅ 数据库结构更新完成"
|
echo "✅ 数据库结构更新完成"
|
||||||
@@ -873,30 +877,30 @@ EOF
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 清理临时文件
|
# 清理临时文件
|
||||||
rm -f temp_migration.sql
|
rm -f temp_migration.sql
|
||||||
|
|
||||||
echo "✅ 更新完成"
|
echo "✅ 更新完成"
|
||||||
}
|
}
|
||||||
|
|
||||||
# 导出数据库备份
|
# 导出数据库备份
|
||||||
export_migration_sql() {
|
export_migration_sql() {
|
||||||
echo "📄 开始导出数据库备份..."
|
echo "📄 开始导出数据库备份..."
|
||||||
|
|
||||||
# 获取数据库配置信息
|
# 获取数据库配置信息
|
||||||
echo "🔍 获取数据库配置信息..."
|
echo "🔍 获取数据库配置信息..."
|
||||||
|
|
||||||
# 先检查后端容器是否在运行
|
# 先检查后端容器是否在运行
|
||||||
if ! docker ps --format "{{.Names}}" | grep -q "^springboot-backend$"; then
|
if ! docker ps --format "{{.Names}}" | grep -q "^springboot-backend$"; then
|
||||||
echo "❌ 后端容器未运行,尝试从 .env 文件读取配置..."
|
echo "❌ 后端容器未运行,尝试从 .env 文件读取配置..."
|
||||||
|
|
||||||
# 从 .env 文件读取配置
|
# 从 .env 文件读取配置
|
||||||
if [[ -f ".env" ]]; then
|
if [[ -f ".env" ]]; then
|
||||||
DB_NAME=$(grep "^DB_NAME=" .env | cut -d'=' -f2 2>/dev/null)
|
DB_NAME=$(grep "^DB_NAME=" .env | cut -d'=' -f2 2>/dev/null)
|
||||||
DB_PASSWORD=$(grep "^DB_PASSWORD=" .env | cut -d'=' -f2 2>/dev/null)
|
DB_PASSWORD=$(grep "^DB_PASSWORD=" .env | cut -d'=' -f2 2>/dev/null)
|
||||||
DB_USER=$(grep "^DB_USER=" .env | cut -d'=' -f2 2>/dev/null)
|
DB_USER=$(grep "^DB_USER=" .env | cut -d'=' -f2 2>/dev/null)
|
||||||
|
|
||||||
if [[ -n "$DB_NAME" && -n "$DB_PASSWORD" && -n "$DB_USER" ]]; then
|
if [[ -n "$DB_NAME" && -n "$DB_PASSWORD" && -n "$DB_USER" ]]; then
|
||||||
echo "✅ 从 .env 文件读取数据库配置成功"
|
echo "✅ 从 .env 文件读取数据库配置成功"
|
||||||
else
|
else
|
||||||
@@ -910,21 +914,21 @@ export_migration_sql() {
|
|||||||
else
|
else
|
||||||
# 从容器环境变量获取数据库信息
|
# 从容器环境变量获取数据库信息
|
||||||
DB_INFO=$(docker exec springboot-backend env | grep "^DB_" 2>/dev/null || echo "")
|
DB_INFO=$(docker exec springboot-backend env | grep "^DB_" 2>/dev/null || echo "")
|
||||||
|
|
||||||
if [[ -n "$DB_INFO" ]]; then
|
if [[ -n "$DB_INFO" ]]; then
|
||||||
DB_NAME=$(echo "$DB_INFO" | grep "^DB_NAME=" | cut -d'=' -f2)
|
DB_NAME=$(echo "$DB_INFO" | grep "^DB_NAME=" | cut -d'=' -f2)
|
||||||
DB_PASSWORD=$(echo "$DB_INFO" | grep "^DB_PASSWORD=" | cut -d'=' -f2)
|
DB_PASSWORD=$(echo "$DB_INFO" | grep "^DB_PASSWORD=" | cut -d'=' -f2)
|
||||||
DB_USER=$(echo "$DB_INFO" | grep "^DB_USER=" | cut -d'=' -f2)
|
DB_USER=$(echo "$DB_INFO" | grep "^DB_USER=" | cut -d'=' -f2)
|
||||||
|
|
||||||
echo "✅ 从容器环境变量读取数据库配置成功"
|
echo "✅ 从容器环境变量读取数据库配置成功"
|
||||||
else
|
else
|
||||||
echo "❌ 无法从容器获取数据库配置,尝试从 .env 文件读取..."
|
echo "❌ 无法从容器获取数据库配置,尝试从 .env 文件读取..."
|
||||||
|
|
||||||
if [[ -f ".env" ]]; then
|
if [[ -f ".env" ]]; then
|
||||||
DB_NAME=$(grep "^DB_NAME=" .env | cut -d'=' -f2 2>/dev/null)
|
DB_NAME=$(grep "^DB_NAME=" .env | cut -d'=' -f2 2>/dev/null)
|
||||||
DB_PASSWORD=$(grep "^DB_PASSWORD=" .env | cut -d'=' -f2 2>/dev/null)
|
DB_PASSWORD=$(grep "^DB_PASSWORD=" .env | cut -d'=' -f2 2>/dev/null)
|
||||||
DB_USER=$(grep "^DB_USER=" .env | cut -d'=' -f2 2>/dev/null)
|
DB_USER=$(grep "^DB_USER=" .env | cut -d'=' -f2 2>/dev/null)
|
||||||
|
|
||||||
if [[ -n "$DB_NAME" && -n "$DB_PASSWORD" && -n "$DB_USER" ]]; then
|
if [[ -n "$DB_NAME" && -n "$DB_PASSWORD" && -n "$DB_USER" ]]; then
|
||||||
echo "✅ 从 .env 文件读取数据库配置成功"
|
echo "✅ 从 .env 文件读取数据库配置成功"
|
||||||
else
|
else
|
||||||
@@ -937,17 +941,17 @@ export_migration_sql() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 检查必要的数据库配置
|
# 检查必要的数据库配置
|
||||||
if [[ -z "$DB_PASSWORD" || -z "$DB_USER" || -z "$DB_NAME" ]]; then
|
if [[ -z "$DB_PASSWORD" || -z "$DB_USER" || -z "$DB_NAME" ]]; then
|
||||||
echo "❌ 数据库配置不完整(缺少必要参数)"
|
echo "❌ 数据库配置不完整(缺少必要参数)"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "📋 数据库配置:"
|
echo "📋 数据库配置:"
|
||||||
echo " 数据库名: $DB_NAME"
|
echo " 数据库名: $DB_NAME"
|
||||||
echo " 用户名: $DB_USER"
|
echo " 用户名: $DB_USER"
|
||||||
|
|
||||||
# 检查数据库容器是否运行
|
# 检查数据库容器是否运行
|
||||||
if ! docker ps --format "{{.Names}}" | grep -q "^gost-mysql$"; then
|
if ! docker ps --format "{{.Names}}" | grep -q "^gost-mysql$"; then
|
||||||
echo "❌ 数据库容器未运行,无法导出数据"
|
echo "❌ 数据库容器未运行,无法导出数据"
|
||||||
@@ -955,11 +959,11 @@ export_migration_sql() {
|
|||||||
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
|
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 生成数据库备份文件
|
# 生成数据库备份文件
|
||||||
SQL_FILE="database_backup_$(date +%Y%m%d_%H%M%S).sql"
|
SQL_FILE="database_backup_$(date +%Y%m%d_%H%M%S).sql"
|
||||||
echo "📝 导出数据库备份: $SQL_FILE"
|
echo "📝 导出数据库备份: $SQL_FILE"
|
||||||
|
|
||||||
# 使用 mysqldump 导出数据库
|
# 使用 mysqldump 导出数据库
|
||||||
echo "⏳ 正在导出数据库..."
|
echo "⏳ 正在导出数据库..."
|
||||||
if docker exec gost-mysql mysqldump -u "$DB_USER" -p"$DB_PASSWORD" --single-transaction --routines --triggers "$DB_NAME" > "$SQL_FILE" 2>/dev/null; then
|
if docker exec gost-mysql mysqldump -u "$DB_USER" -p"$DB_PASSWORD" --single-transaction --routines --triggers "$DB_NAME" > "$SQL_FILE" 2>/dev/null; then
|
||||||
@@ -974,7 +978,7 @@ export_migration_sql() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 检查文件大小
|
# 检查文件大小
|
||||||
if [[ -f "$SQL_FILE" ]] && [[ -s "$SQL_FILE" ]]; then
|
if [[ -f "$SQL_FILE" ]] && [[ -s "$SQL_FILE" ]]; then
|
||||||
FILE_SIZE=$(du -h "$SQL_FILE" | cut -f1)
|
FILE_SIZE=$(du -h "$SQL_FILE" | cut -f1)
|
||||||
@@ -987,11 +991,44 @@ export_migration_sql() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ===================== 新增:安装并配置反向代理(Caddy) =====================
|
||||||
|
install_reverse_proxy() {
|
||||||
|
echo "🚀 开始安装并配置 Caddy 反向代理..."
|
||||||
|
# 尽量读取前端端口作为反代后端端口的建议值
|
||||||
|
FRONTEND_HINT=""
|
||||||
|
if [[ -f ".env" ]]; then
|
||||||
|
ENV_FRONTEND_PORT=$(grep "^FRONTEND_PORT=" .env | cut -d'=' -f2 2>/dev/null || echo "")
|
||||||
|
if [[ -n "$ENV_FRONTEND_PORT" ]]; then
|
||||||
|
FRONTEND_HINT="$ENV_FRONTEND_PORT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "📥 下载 proxy.sh ..."
|
||||||
|
if ! curl -fsSL "$PROXY_SH_URL" -o proxy.sh; then
|
||||||
|
echo "❌ 下载 proxy.sh 失败:$PROXY_SH_URL"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
chmod +x proxy.sh
|
||||||
|
|
||||||
|
echo "ℹ️ 即将启动反代安装脚本。填写建议:"
|
||||||
|
echo " - 反向代理目标地址:建议填 127.0.0.1"
|
||||||
|
if [[ -n "$FRONTEND_HINT" ]]; then
|
||||||
|
echo " - 反向代理目标端口:建议填 $FRONTEND_HINT(从 .env 读取的前端端口)"
|
||||||
|
else
|
||||||
|
echo " - 反向代理目标端口:建议填 6366(默认前端端口)"
|
||||||
|
fi
|
||||||
|
echo " - 其余选项按需选择(是否使用 DNS 验证、邮箱等)"
|
||||||
|
|
||||||
|
./proxy.sh
|
||||||
|
|
||||||
|
echo "✅ 反向代理配置完成"
|
||||||
|
}
|
||||||
|
|
||||||
# 卸载功能
|
# 卸载功能
|
||||||
uninstall_panel() {
|
uninstall_panel() {
|
||||||
echo "🗑️ 开始卸载面板..."
|
echo "🗑️ 开始卸载面板..."
|
||||||
check_docker
|
check_docker
|
||||||
|
|
||||||
if [[ ! -f "docker-compose.yml" ]]; then
|
if [[ ! -f "docker-compose.yml" ]]; then
|
||||||
echo "⚠️ 未找到 docker-compose.yml 文件,正在下载以完成卸载..."
|
echo "⚠️ 未找到 docker-compose.yml 文件,正在下载以完成卸载..."
|
||||||
DOCKER_COMPOSE_URL=$(get_docker_compose_url)
|
DOCKER_COMPOSE_URL=$(get_docker_compose_url)
|
||||||
@@ -999,7 +1036,7 @@ uninstall_panel() {
|
|||||||
curl -L -o docker-compose.yml "$DOCKER_COMPOSE_URL"
|
curl -L -o docker-compose.yml "$DOCKER_COMPOSE_URL"
|
||||||
echo "✅ docker-compose.yml 下载完成"
|
echo "✅ docker-compose.yml 下载完成"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
read -p "确认卸载面板吗?此操作将停止并删除所有容器和数据 (y/N): " confirm
|
read -p "确认卸载面板吗?此操作将停止并删除所有容器和数据 (y/N): " confirm
|
||||||
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
|
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
|
||||||
echo "❌ 取消卸载"
|
echo "❌ 取消卸载"
|
||||||
@@ -1020,7 +1057,7 @@ main() {
|
|||||||
while true; do
|
while true; do
|
||||||
show_menu
|
show_menu
|
||||||
read -p "请输入选项 (1-5): " choice
|
read -p "请输入选项 (1-5): " choice
|
||||||
|
|
||||||
case $choice in
|
case $choice in
|
||||||
1)
|
1)
|
||||||
install_panel
|
install_panel
|
||||||
@@ -1043,6 +1080,11 @@ main() {
|
|||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
5)
|
5)
|
||||||
|
install_reverse_proxy
|
||||||
|
delete_self
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
6)
|
||||||
echo "👋 退出脚本"
|
echo "👋 退出脚本"
|
||||||
delete_self
|
delete_self
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -0,0 +1,191 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# caddy-reverse-proxy.sh
|
||||||
|
# 自动安装&配置Caddy反代(支持SSL、DNS验证、IPv6、WS、自动续期免输入)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ENV_FILE="/etc/caddy/dns.env"
|
||||||
|
SYSTEMD_SERVICE="/etc/systemd/system/caddy.service"
|
||||||
|
|
||||||
|
# ===== 用户输入 =====
|
||||||
|
read -rp "请输入反向代理目标地址 (例如 127.0.0.1): " backend_host
|
||||||
|
read -rp "请输入反向代理目标端口 [默认6366]: " backend_port
|
||||||
|
backend_port=${backend_port:-6366}
|
||||||
|
|
||||||
|
read -rp "请输入监听端口 [默认443]: " listen_port
|
||||||
|
listen_port=${listen_port:-443}
|
||||||
|
|
||||||
|
read -rp "请输入反代访问域名 (必须已解析到本机): " domain
|
||||||
|
if [[ -z "$domain" ]]; then
|
||||||
|
echo "❌ 域名必填!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -rp "请输入邮箱(可选,留空则不设置): " ssl_email
|
||||||
|
read -rp "是否使用 DNS 验证申请证书?[y/N]: " use_dns
|
||||||
|
use_dns=${use_dns:-N}
|
||||||
|
|
||||||
|
dns_provider=""
|
||||||
|
declare -A env_vars
|
||||||
|
|
||||||
|
if [[ "$use_dns" =~ ^[Yy]$ ]]; then
|
||||||
|
echo "请选择 DNS 服务商:"
|
||||||
|
echo "1) Cloudflare"
|
||||||
|
echo "2) Dnspod (国内站)"
|
||||||
|
echo "3) Dnspod (国际站)"
|
||||||
|
echo "4) Aliyun (国内)"
|
||||||
|
echo "5) Aliyun (国际)"
|
||||||
|
read -rp "输入编号: " dns_choice
|
||||||
|
|
||||||
|
case $dns_choice in
|
||||||
|
1)
|
||||||
|
dns_provider="cloudflare"
|
||||||
|
read -rp "Cloudflare API Token: " CF_API_TOKEN
|
||||||
|
env_vars["CF_API_TOKEN"]=$CF_API_TOKEN
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
dns_provider="dnspod"
|
||||||
|
read -rp "Dnspod 国内站 API ID: " DP_ID
|
||||||
|
read -rp "Dnspod 国内站 API Key: " DP_KEY
|
||||||
|
env_vars["DP_ID"]=$DP_ID
|
||||||
|
env_vars["DP_KEY"]=$DP_KEY
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
dns_provider="dnspod"
|
||||||
|
read -rp "Dnspod 国际站 API Token: " DP_TOKEN
|
||||||
|
env_vars["DP_TOKEN"]=$DP_TOKEN
|
||||||
|
;;
|
||||||
|
4|5)
|
||||||
|
dns_provider="alidns"
|
||||||
|
read -rp "Aliyun AccessKey ID: " ALICLOUD_ACCESS_KEY
|
||||||
|
read -rp "Aliyun AccessKey Secret: " ALICLOUD_SECRET_KEY
|
||||||
|
env_vars["ALICLOUD_ACCESS_KEY"]=$ALICLOUD_ACCESS_KEY
|
||||||
|
env_vars["ALICLOUD_SECRET_KEY"]=$ALICLOUD_SECRET_KEY
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "❌ 无效选项"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ===== 检查IPv6支持 =====
|
||||||
|
if ping6 -c1 google.com &>/dev/null; then
|
||||||
|
listen_address="[::]"
|
||||||
|
echo "✅ 检测到IPv6支持,将使用IPv6监听"
|
||||||
|
else
|
||||||
|
listen_address="0.0.0.0"
|
||||||
|
echo "⚠️ 未检测到IPv6支持,将使用IPv4监听"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ===== 安装Caddy =====
|
||||||
|
if ! command -v caddy &>/dev/null; then
|
||||||
|
echo "🔧 安装Caddy..."
|
||||||
|
apt update && apt install -y curl unzip
|
||||||
|
|
||||||
|
# 使用官方安装脚本
|
||||||
|
curl -sSfL https://caddyserver.com/static/install.sh | bash -s
|
||||||
|
|
||||||
|
# 或者使用包管理器安装(取消注释以下行)
|
||||||
|
# curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||||||
|
# curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
|
||||||
|
# apt update
|
||||||
|
# apt install caddy
|
||||||
|
|
||||||
|
# 确保caddy在正确位置
|
||||||
|
if [[ -f "/usr/bin/caddy" ]]; then
|
||||||
|
mv /usr/bin/caddy /usr/local/bin/caddy
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p /etc/caddy
|
||||||
|
|
||||||
|
# ===== 保存环境变量到dns.env =====
|
||||||
|
echo "# Caddy DNS Provider API Keys" >"$ENV_FILE"
|
||||||
|
for key in "${!env_vars[@]}"; do
|
||||||
|
echo "$key=${env_vars[$key]}" >>"$ENV_FILE"
|
||||||
|
done
|
||||||
|
chmod 600 "$ENV_FILE"
|
||||||
|
|
||||||
|
# ===== 配置systemd服务加载环境变量 =====
|
||||||
|
cat >"$SYSTEMD_SERVICE" <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Caddy web server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=root
|
||||||
|
EnvironmentFile=$ENV_FILE
|
||||||
|
ExecStart=/usr/local/bin/caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
|
||||||
|
ExecReload=/usr/local/bin/caddy reload --config /etc/caddy/Caddyfile --adapter caddyfile
|
||||||
|
Restart=on-abnormal
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# ===== 全局配置 =====
|
||||||
|
if [[ -n "$ssl_email" ]]; then
|
||||||
|
global_cfg="{ email $ssl_email }"
|
||||||
|
else
|
||||||
|
global_cfg="{}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ===== 生成Caddyfile =====
|
||||||
|
if [[ -n "$dns_provider" ]]; then
|
||||||
|
cat >/etc/caddy/Caddyfile <<EOF
|
||||||
|
$global_cfg
|
||||||
|
|
||||||
|
https://$domain:$listen_port {
|
||||||
|
bind $listen_address
|
||||||
|
encode gzip
|
||||||
|
tls {
|
||||||
|
dns $dns_provider
|
||||||
|
}
|
||||||
|
@websockets {
|
||||||
|
header Connection *Upgrade*
|
||||||
|
header Upgrade websocket
|
||||||
|
}
|
||||||
|
reverse_proxy $backend_host:$backend_port {
|
||||||
|
header_up Host {host}
|
||||||
|
header_up X-Real-IP {remote_host}
|
||||||
|
header_up X-Forwarded-For {remote_host}
|
||||||
|
header_up X-Forwarded-Proto {scheme}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http://$domain:80 {
|
||||||
|
redir https://$domain:$listen_port{uri} permanent
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
cat >/etc/caddy/Caddyfile <<EOF
|
||||||
|
$global_cfg
|
||||||
|
|
||||||
|
https://$domain:$listen_port {
|
||||||
|
bind $listen_address
|
||||||
|
encode gzip
|
||||||
|
@websockets {
|
||||||
|
header Connection *Upgrade*
|
||||||
|
header Upgrade websocket
|
||||||
|
}
|
||||||
|
reverse_proxy $backend_host:$backend_port {
|
||||||
|
header_up Host {host}
|
||||||
|
header_up X-Real-IP {remote_host}
|
||||||
|
header_up X-Forwarded-For {remote_host}
|
||||||
|
header_up X-Forwarded-Proto {scheme}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http://$domain:80 {
|
||||||
|
redir https://$domain:$listen_port{uri} permanent
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ===== 重启Caddy =====
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable caddy
|
||||||
|
systemctl restart caddy
|
||||||
|
|
||||||
|
echo "✅ Caddy反代已部署完成"
|
||||||
|
echo "🔑 证书续期将自动使用 $ENV_FILE 中的DNS API Key,无需再次输入"
|
||||||
|
echo "访问地址:https://$domain:$listen_port"
|
||||||
@@ -258,6 +258,18 @@ curl -L https://your-panel-server:6365/agent/install | bash -s -- --server=your-
|
|||||||
|
|
||||||
4. 点击 **"确定"** 保存限速规则
|
4. 点击 **"确定"** 保存限速规则
|
||||||
|
|
||||||
|
## 第九步:API流量信息查询(可选)
|
||||||
|
- 本项目为sub-store提供流量查询API以便查询流量日期信息
|
||||||
|
- 格式如下
|
||||||
|
```
|
||||||
|
http(s)://<面板连接地址>/api/v1/open_api/sub_store?user=<用户名>&pwd=<密码>&tunnel=<隧道ID>
|
||||||
|
```
|
||||||
|
- 修改完成后填入sub-store订阅流量信息栏即可实现查询
|
||||||
|
**注意**
|
||||||
|
- “&tunnel=隧道id”为可选项,若不填写则返回全部流量查询信息
|
||||||
|
- 管理员无此查询权限
|
||||||
|
- 请妥善保存上述信息,避免因用户信息泄漏而造成的损失
|
||||||
|
|
||||||
## 获取帮助
|
## 获取帮助
|
||||||
|
|
||||||
### 社区支持
|
### 社区支持
|
||||||
|
|||||||
Reference in New Issue
Block a user