- deploy/docker-compose.dev.yml 新增 media-server 服务 + coturn(profiles:public),
全部服务参数改为 env 变量注入,go-service 依赖 media-server
- deploy/.env.example / .env.local.example / .env.public.example 三份模板,
公网模板用 _REPLACE_WITH_*_ 占位符防"示例值上生产"
- scripts/start.sh / stop.sh / status.sh 新增 full 子命令对接 docker compose --profile public
- scripts/deploy-public.sh 新建:env 校验 + 端口 checklist + Docker 自检 +
--profile public up -d --build + 健康检查闭环
- docs/deployment/meeting-mvp.md 新建:双态部署全流程 + 强密码生成 + 防火墙 + FAQ
- 双模式 docker compose config 校验通过;deploy-public.sh 三种错误场景按预期退出
同步更新 CURRENT_STATUS / implementation.plan / project-context
Task 0-14 ✅ / 剩余 Task 15-16
Made-with: Cursor
135 lines
3.9 KiB
Bash
Executable File
135 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# EchoChat 一键停止脚本
|
||
# 用法:
|
||
# ./scripts/stop.sh # 停止应用层(Go 后端 + 前台 + 管理端 + 媒体),保留 Docker 容器
|
||
# ./scripts/stop.sh --all # 停止全部(含 Docker 中间件)
|
||
# ./scripts/stop.sh full # 停止 docker compose 全栈(含 media-server 容器,含 public profile 的 coturn)
|
||
# ./scripts/stop.sh backend # 仅停止指定服务(backend|frontend|admin|media|docker)
|
||
# 不使用 set -e:即使某一项停止失败,其他项也要继续尝试
|
||
set -uo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||
RUN_DIR="$ROOT_DIR/.run"
|
||
DEPLOY_DIR="$ROOT_DIR/deploy"
|
||
|
||
COLOR_GREEN='\033[0;32m'
|
||
COLOR_YELLOW='\033[0;33m'
|
||
COLOR_RED='\033[0;31m'
|
||
COLOR_CYAN='\033[0;36m'
|
||
COLOR_RESET='\033[0m'
|
||
|
||
log_info() { printf "${COLOR_CYAN}[INFO]${COLOR_RESET} %s\n" "$*"; }
|
||
log_ok() { printf "${COLOR_GREEN}[OK]${COLOR_RESET} %s\n" "$*"; }
|
||
log_warn() { printf "${COLOR_YELLOW}[WARN]${COLOR_RESET} %s\n" "$*"; }
|
||
|
||
# 根据端口查找监听进程 PID
|
||
pids_by_port() {
|
||
lsof -iTCP:"$1" -sTCP:LISTEN -n -P -t 2>/dev/null || true
|
||
}
|
||
|
||
# 终止 PID(先 TERM,2s 后仍存在则 KILL),同时杀掉其子进程组
|
||
kill_pid() {
|
||
local pid="$1"
|
||
[[ -z "$pid" ]] && return 0
|
||
kill -0 "$pid" 2>/dev/null || return 0
|
||
# 尝试杀死进程组(负 PID 表示进程组)
|
||
kill -TERM -"$pid" 2>/dev/null || kill -TERM "$pid" 2>/dev/null || true
|
||
for _ in 1 2 3 4; do
|
||
kill -0 "$pid" 2>/dev/null || return 0
|
||
sleep 0.5
|
||
done
|
||
kill -KILL -"$pid" 2>/dev/null || kill -KILL "$pid" 2>/dev/null || true
|
||
}
|
||
|
||
# 停止由 start.sh 启动的命名服务(以 .pid 文件 + 端口兜底)
|
||
stop_named() {
|
||
local name="$1"
|
||
local port="$2"
|
||
local pid_file="$RUN_DIR/$name.pid"
|
||
local killed=0
|
||
|
||
if [[ -f "$pid_file" ]]; then
|
||
local pid
|
||
pid="$(cat "$pid_file")"
|
||
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
||
log_info "停止 $name (PID=$pid, port=$port)..."
|
||
kill_pid "$pid"
|
||
killed=1
|
||
fi
|
||
rm -f "$pid_file"
|
||
fi
|
||
|
||
# 端口兜底:清理任何仍占用目标端口的进程
|
||
local port_pids
|
||
port_pids="$(pids_by_port "$port")"
|
||
if [[ -n "$port_pids" ]]; then
|
||
for p in $port_pids; do
|
||
log_info "清理 $name 残留进程 (PID=$p, port=$port)..."
|
||
kill_pid "$p"
|
||
killed=1
|
||
done
|
||
fi
|
||
|
||
if [[ $killed -eq 1 ]]; then
|
||
log_ok "$name 已停止"
|
||
else
|
||
log_warn "$name 未在运行"
|
||
fi
|
||
}
|
||
|
||
stop_backend() { stop_named "backend" 8085; }
|
||
stop_frontend() { stop_named "frontend" 5173; }
|
||
stop_admin() { stop_named "admin" 3100; }
|
||
stop_media() { stop_named "media" 3300; }
|
||
|
||
stop_docker() {
|
||
log_info "停止 Docker 中间件..."
|
||
cd "$ROOT_DIR/deploy"
|
||
docker compose -f docker-compose.dev.yml stop postgres redis minio || true
|
||
log_ok "Docker 中间件已停止(数据卷保留)"
|
||
}
|
||
|
||
# Phase 2e-2 Task 14:停止 docker compose 全栈(含 media-server、coturn)
|
||
# 使用 --profile public 确保即使 coturn 在 public profile 下运行也能被停掉
|
||
stop_full() {
|
||
log_info "停止 docker compose 全栈(含 media-server / coturn)..."
|
||
cd "$DEPLOY_DIR"
|
||
docker compose -f docker-compose.dev.yml --profile public stop || true
|
||
log_ok "全栈服务已停止(数据卷保留)"
|
||
}
|
||
|
||
main() {
|
||
local target="${1:-app}"
|
||
|
||
case "$target" in
|
||
app|"")
|
||
stop_backend
|
||
stop_media
|
||
stop_frontend
|
||
stop_admin
|
||
log_ok "应用层服务已停止(Docker 中间件保持运行)"
|
||
;;
|
||
--all|all)
|
||
stop_backend
|
||
stop_media
|
||
stop_frontend
|
||
stop_admin
|
||
stop_docker
|
||
log_ok "所有服务已停止"
|
||
;;
|
||
backend) stop_backend ;;
|
||
frontend) stop_frontend ;;
|
||
admin) stop_admin ;;
|
||
media) stop_media ;;
|
||
docker) stop_docker ;;
|
||
full) stop_full ;;
|
||
*)
|
||
echo "用法: $0 [app|--all|backend|frontend|admin|media|docker|full]"
|
||
exit 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
main "$@"
|