Files
2026-10-13 21:52:02 +08:00

139 lines
6.9 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
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
# ============================================================
# 捕鱼/棋牌平台 - 一键部署脚本(Linux 服务器 + Docker)
#
# 用法:
# bash deploy/deploy.sh
# PUBLIC_HOST=1.2.3.4:8001 bash deploy/deploy.sh # 指定客户端访问地址(含端口)
#
# 前置要求:
# - Linux 服务器已安装 Docker(含 docker compose v2 插件)
# - 服务器可访问 nuget.org 与 docker hub(首次编译需要联网拉取依赖)
# - 建议预留 5GB 以上磁盘空间
#
# 脚本做的事:
# 1. 在 dotnet/sdk:8.0 容器内编译发布 7 个 Host(服务器无需安装 .NET SDK)
# 2. 覆盖各服务的部署版 Config/system.json,并把网关下游地址改写为容器名
# 3. 构建 7 个镜像(0524gateway / 0524admin / 0524user / 0524customer /
# 0524chess / 0524fishroom / 0524fishgame)
# 4. 启动全部容器(4 个中间件 + 7 个应用)并做健康检查
#
# 常用运维命令:
# 查看状态:docker compose -f deploy/docker-compose.yml ps
# 查看日志:docker compose -f deploy/docker-compose.yml logs -f <服务名>
# 停止全部:docker compose -f deploy/docker-compose.yml down
# ============================================================
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
DEPLOY_DIR="$ROOT/deploy"
PUB_DIR="$DEPLOY_DIR/publish"
COMPOSE_FILE="$DEPLOY_DIR/docker-compose.yml"
SDK_IMAGE="mcr.microsoft.com/dotnet/sdk:8.0"
NUGET_VOLUME="buyu-nuget"
log() { echo -e "\033[1;32m[部署]\033[0m $*"; }
warn() { echo -e "\033[1;33m[警告]\033[0m $*"; }
# 客户端访问地址(用于捕鱼对局层返回给客户端的 WebSocket 地址);不传则自动取本机第一个 IP
if [ -z "${PUBLIC_HOST:-}" ]; then
SERVER_IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
PUBLIC_HOST="${SERVER_IP:-localhost}:8001"
fi
# ---------- 0. 环境检查 ----------
command -v docker >/dev/null 2>&1 || { echo "未检测到 docker,请先安装 Docker"; exit 1; }
docker compose version >/dev/null 2>&1 || { echo "未检测到 docker compose v2,请安装 docker-compose-plugin"; exit 1; }
[ -f "$COMPOSE_FILE" ] || { echo "缺少编排文件:$COMPOSE_FILE"; exit 1; }
# ---------- 1. 容器内编译发布 + 准备部署配置 ----------
log "1/4 编译发布(在容器内进行,首次需要拉取 SDK 镜像与 NuGet 包,耗时较长)..."
docker run --rm \
-v "$ROOT":/src \
-w /src \
-v "$NUGET_VOLUME":/root/.nuget/packages \
-e PUBLIC_HOST="$PUBLIC_HOST" \
"$SDK_IMAGE" bash -c '
set -e
rm -rf /src/deploy/publish
mkdir -p /src/deploy/publish
dotnet publish Gateway/Gateway.csproj -c Release -o /src/deploy/publish/gateway --nologo
dotnet publish AdminSrc/AdminHost/AdminHost.csproj -c Release -o /src/deploy/publish/admin --nologo
dotnet publish UserSrc/UserHost/UserHost.csproj -c Release -o /src/deploy/publish/user --nologo
dotnet publish CustomerSrc/CustomerHost/CustomerHost.csproj -c Release -o /src/deploy/publish/customer --nologo
dotnet publish ChessGameHost/ChessGameHost.csproj -c Release -o /src/deploy/publish/chess --nologo
dotnet publish FishGameSrc/FishRoomHost/FishRoomHost.csproj -c Release -o /src/deploy/publish/fishroom --nologo
dotnet publish FishGameSrc/FishGameHost/FishGameHost.csproj -c Release -o /src/deploy/publish/fishgame --nologo
# 覆盖部署版配置(各 Host 的 Config/system.json 默认不会随发布输出,必须显式拷贝)
for name in gateway admin user customer chess fishroom fishgame; do
mkdir -p /src/deploy/publish/$name/Config
cp /src/deploy/config/$name/system.json /src/deploy/publish/$name/Config/system.json
cp /src/nlog.config /src/deploy/publish/$name/nlog.config
done
# 捕鱼对局层:替换客户端要访问的 WebSocket 地址(经网关 /gamehub 路由)
sed -i "s|__PUBLIC_HOST__|$PUBLIC_HOST|g" /src/deploy/publish/fishgame/Config/system.json
# 网关:ocelot 下游地址由 localhost:524x 改写为「容器名:80」(容器间互访)
OCELOT=/src/deploy/publish/gateway/ocelot.json
sed -i \
-e "s|{ \"Host\": \"localhost\", \"Port\": 5241 }|{ \"Host\": \"0524admin\", \"Port\": 80 }|" \
-e "s|{ \"Host\": \"localhost\", \"Port\": 5245 }|{ \"Host\": \"0524user\", \"Port\": 80 }|" \
-e "s|{ \"Host\": \"localhost\", \"Port\": 5247 }|{ \"Host\": \"0524customer\", \"Port\": 80 }|" \
-e "s|{ \"Host\": \"localhost\", \"Port\": 5242 }|{ \"Host\": \"0524chess\", \"Port\": 80 }|" \
-e "s|{ \"Host\": \"localhost\", \"Port\": 5244 }|{ \"Host\": \"0524fishroom\", \"Port\": 80 }|" \
-e "s|{ \"Host\": \"localhost\", \"Port\": 5248 }|{ \"Host\": \"0524fishgame\", \"Port\": 80 }|" \
"$OCELOT"
'
# ---------- 2. 构建 7 个应用镜像 ----------
log "2/4 构建镜像..."
build_image() { # 镜像名 入口dll 发布目录名
docker build -f "$DEPLOY_DIR/Dockerfile" --build-arg "APP_DLL=$2" -t "$1" "$PUB_DIR/$3"
echo " ✔ $1"
}
build_image 0524gateway Gateway.dll gateway
build_image 0524admin AdminHost.dll admin
build_image 0524user UserHost.dll user
build_image 0524customer CustomerHost.dll customer
build_image 0524chess ChessGameHost.dll chess
build_image 0524fishroom FishRoomHost.dll fishroom
build_image 0524fishgame FishGameHost.dll fishgame
# ---------- 3. 启动全部容器 ----------
log "3/4 启动容器(4 个中间件 + 7 个应用)..."
mkdir -p "$DEPLOY_DIR"/logs/{gateway,admin,user,customer,chess,fishroom,fishgame}
mkdir -p "$DEPLOY_DIR"/uploads/{admin,user,customer}
docker compose -f "$COMPOSE_FILE" up -d
# ---------- 4. 健康检查 ----------
log "4/4 等待服务就绪..."
sleep 8
check() { # 地址 服务名
for _ in $(seq 1 15); do
if curl -fsS -o /dev/null --max-time 2 "$1"; then
echo " ✔ $2 $1"
return 0
fi
sleep 2
done
warn "$2 未就绪:$1(排查:docker compose -f deploy/docker-compose.yml logs $2)"
}
check "http://localhost:8001/health" gateway
check "http://localhost:5241/health" admin
check "http://localhost:5245/health" user
check "http://localhost:5247/health" customer
check "http://localhost:5242/health" chess
check "http://localhost:5244/health" fishroom
check "http://localhost:5248/health" fishgame
echo ""
log "部署完成"
echo "----------------------------------------------------------"
echo " 统一入口(网关) : http://$PUBLIC_HOST"
echo " RabbitMQ 控制台 : http://<服务器IP>:15672(admin / 123456)"
echo " 日志目录 : deploy/logs/<服务名>/日期/"
echo " 上传文件目录 : deploy/uploads/<服务名>/"
echo " 停止全部 : docker compose -f deploy/docker-compose.yml down"
echo "----------------------------------------------------------"