From db787d60755f09bdb743195e2317445c9f791e15 Mon Sep 17 00:00:00 2001 From: vet Date: Mon, 13 Apr 2026 22:25:56 +0700 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 01-init-env.sh | 21 +++++++++++-------- 02-patch-config.sh | 51 ++++++++++++++++------------------------------ 03-start-infra.sh | 51 +++++++++++++++++++++++++++++++++++++++++++++- README.md | 37 ++++++++++++++++++++------------- check-conn.sh | 20 +++++++++--------- logs.sh | 1 + remove-infra.sh | 4 ++-- restart.sh | 3 ++- setup.sh | 6 +++--- status.sh | 5 +++-- stop-infra.sh | 6 ++++-- 11 files changed, 128 insertions(+), 77 deletions(-) diff --git a/01-init-env.sh b/01-init-env.sh index 0dd3a80..90319fc 100755 --- a/01-init-env.sh +++ b/01-init-env.sh @@ -46,15 +46,18 @@ MONGO_AUTHSOURCE=admin # 连接 URI 中 authSource=…,须与创建 MONGO_DATABASE=openim_v3 # open-im-server / chat 业务库名 BUILD_MONGO_DATABASE=build # build-server 使用 -# ── Amazon S3 — open-im-server(IM 聊天文件存储,必填)────────────────────── -# 对应 open-im-server/config/openim-rpc-third.yml → object.aws -OPENIM_AWS_REGION=ap-southeast-1 -OPENIM_AWS_BUCKET=im1688 -OPENIM_AWS_ACCESS_KEY_ID=AKIA5TMMSZWVFYCLKJ2G -OPENIM_AWS_SECRET_ACCESS_KEY=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 -# 自定义 Endpoint(CloudFlare R2 / 其他 S3 兼容服务),留空则使用 AWS 官方 -OPENIM_AWS_ENDPOINT= -OPENIM_AWS_PUBLIC_READ=true +# ── MinIO(Docker 本机 dev-minio,open-im-server 对象存储,必填)────────────── +# 对应 open-im-server/config/minio.yml + openim-rpc-third.yml → object.enable: minio +# 03-start-infra.sh 会启动容器并映射端口;本机服务用 internal,手机/外网用 external +MINIO_ROOT_USER=minioadmin +MINIO_ROOT_PASSWORD=openIM123minio +MINIO_BUCKET=openim +MINIO_API_PORT=9000 +MINIO_CONSOLE_PORT=9001 +MINIO_INTERNAL_ADDRESS=127.0.0.1:9000 +# 外网访问地址(与 DEPLOY_TEST_IP 一致,客户端下载/预览文件用)。须安全组放行 TCP ${MINIO_API_PORT} +MINIO_EXTERNAL_ADDRESS=http://54.116.29.247:9000 +MINIO_PUBLIC_READ=true # ── Amazon S3 — build-server(App APK/IPA 构建产物存储,必填)─────────────── # 对应 build-server/config/config.yaml → aws diff --git a/02-patch-config.sh b/02-patch-config.sh index 73c77d4..b704087 100755 --- a/02-patch-config.sh +++ b/02-patch-config.sh @@ -110,57 +110,42 @@ maxRetry: 10 EOF success " mongodb.yml → ${MONGO_HOST}:${MONGO_PORT}/${MONGO_DATABASE}" -# minio.yml(标记已切换至 S3,实际由 openim-rpc-third.yml 控制) +# minio.yml(Docker MinIO,与 openim-rpc-third object.enable: minio 配套) cat > "$OPENIM_CONF/minio.yml" </ # 容器日志: .local-dev/docker-logs//-YYYYMMDD.log(每日一文件) @@ -191,6 +191,54 @@ else fi start_docker_logger "dev-etcd" +# ────────────────────────────────────────────────────────────────────────────── +# MinIO(S3 兼容对象存储,映射到宿主机供本机与外网访问) +# ────────────────────────────────────────────────────────────────────────────── +step "MinIO" + +MINIO_API_PORT="${MINIO_API_PORT:-9000}" +MINIO_CONSOLE_PORT="${MINIO_CONSOLE_PORT:-9001}" +MINIO_ROOT_USER="${MINIO_ROOT_USER:-minioadmin}" +MINIO_ROOT_PASSWORD="${MINIO_ROOT_PASSWORD:-openIM123minio}" +MINIO_BUCKET="${MINIO_BUCKET:-openim}" +MINIO_EXTERNAL_ADDRESS="${MINIO_EXTERNAL_ADDRESS:-http://${DEPLOY_TEST_IP}:${MINIO_API_PORT}}" + +if docker ps --format '{{.Names}}' | grep -q '^dev-minio$'; then + success "MinIO 已在运行 (container=dev-minio) API :${MINIO_API_PORT} Console :${MINIO_CONSOLE_PORT}" +elif docker ps -a --format '{{.Names}}' | grep -q '^dev-minio$'; then + info "重新启动已有容器 dev-minio..." + docker start dev-minio > /dev/null + success "MinIO 已启动 API :${MINIO_API_PORT}" +else + info "创建并启动 MinIO 容器..." + mkdir -p "${DATA_DIR}/minio" + docker run -d \ + --name dev-minio \ + --restart unless-stopped \ + -p "${MINIO_API_PORT}:9000" \ + -p "${MINIO_CONSOLE_PORT}:9001" \ + -e MINIO_ROOT_USER="${MINIO_ROOT_USER}" \ + -e MINIO_ROOT_PASSWORD="${MINIO_ROOT_PASSWORD}" \ + -e MINIO_SERVER_URL="${MINIO_EXTERNAL_ADDRESS}" \ + -v "${DATA_DIR}/minio:/data" \ + "${LOG_OPTS[@]}" \ + minio/minio:latest \ + server /data --console-address ":9001" \ + > /dev/null + success "MinIO 容器已创建 API :${MINIO_API_PORT} Console :${MINIO_CONSOLE_PORT}" +fi + +sleep 2 +if docker run --rm --network container:dev-minio minio/mc:latest \ + sh -c "mc alias set local http://127.0.0.1:9000 '${MINIO_ROOT_USER}' '${MINIO_ROOT_PASSWORD}' && mc mb local/${MINIO_BUCKET} --ignore-existing" \ + &>/dev/null; then + success "MinIO bucket「${MINIO_BUCKET}」已就绪" +else + warn "MinIO bucket 初始化未确认(可稍后手动: mc mb)" +fi +info " 本机 API: 127.0.0.1:${MINIO_API_PORT} 外网: ${MINIO_EXTERNAL_ADDRESS}(须放行 TCP ${MINIO_API_PORT})" +start_docker_logger "dev-minio" + # ────────────────────────────────────────────────────────────────────────────── # LiveKit(本地 Docker 容器,复用 dev-redis) # ────────────────────────────────────────────────────────────────────────────── @@ -249,6 +297,7 @@ echo -e "${BOLD}基础设施状态:${NC}" print_container_status "Redis" "dev-redis" "${REDIS_PORT}" print_container_status "Kafka" "dev-kafka" "${KAFKA_PORT}" print_container_status "Etcd" "dev-etcd" "${ETCD_PORT}" +print_container_status "MinIO" "dev-minio" "${MINIO_API_PORT:-9000}" print_container_status "LiveKit" "dev-livekit" "7880" echo "" echo -e "${BOLD}日志目录:${NC}" diff --git a/README.md b/README.md index 8c7233b..31d0054 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ | 配置文件 | `.env.deploy-test` | `.env.deploy-local` | | 运行时目录 | `.deploy-test/` | `.deploy-local/` | | LiveKit | 本机 Docker 启动,使用公网 IP | 指向本目录服务器的 LiveKit | -| Redis/Kafka/Etcd | 本机 Docker | 本机 Docker | +| Redis/Kafka/Etcd/MinIO | 本机 Docker | 本机 Docker | | 后端服务 | 本机进程 | 本机进程 | | 前端服务 | 本机进程(可选) | 本机进程 | @@ -28,7 +28,7 @@ deploy-test/ ├── common.sh # 公共函数库(路径、日志函数) ├── 01-init-env.sh # 步骤1:写入 .env.deploy-test(已存在则覆盖,旧文件带时间戳备份) ├── 02-patch-config.sh # 步骤2:将 .env.deploy-test 写入各服务 YAML -├── 03-start-infra.sh # 步骤3:启动 Docker 容器(Redis/Kafka/Etcd/LiveKit) +├── 03-start-infra.sh # 步骤3:启动 Docker 容器(Redis/Kafka/Etcd/MinIO/LiveKit) ├── 04-build.sh # 步骤4:编译所有后端 Go 服务 ├── 05-start.sh # 步骤5:启动所有后端服务 ├── 06-install-frontend.sh # 步骤6:安装前端依赖(可选) @@ -40,7 +40,7 @@ deploy-test/ ├── restart.sh # 重启指定服务(支持 --build) ├── status.sh # 查看所有服务状态 ├── logs.sh # 查看日志(统一入口) -├── check-conn.sh # 验证 MongoDB / S3 连接 +├── check-conn.sh # 验证 MongoDB / MinIO(及 build-server 的 S3)连接 └── setup.sh # 一键完整部署(首次使用) ``` @@ -111,7 +111,7 @@ vim .env.deploy-test # 3. 将配置写入各服务 YAML(包括 livekit/livekit.yaml) ./deploy-test/02-patch-config.sh -# 4. 启动 Docker 基础设施(Redis / Kafka / Etcd / LiveKit) +# 4. 启动 Docker 基础设施(Redis / Kafka / Etcd / MinIO / LiveKit) ./deploy-test/03-start-infra.sh # 5. 编译后端服务 @@ -148,18 +148,24 @@ MONGO_AUTHSOURCE=admin # 认证库(常见 admin);须与 MongoDB MONGO_DATABASE=openim_v3 # 业务数据所在库 BUILD_MONGO_DATABASE=build -# ══ Amazon S3 ══════════════════════════════════════════════════ -OPENIM_AWS_REGION=ap-southeast-1 -OPENIM_AWS_BUCKET=im1688 -OPENIM_AWS_ACCESS_KEY_ID=xxx -OPENIM_AWS_SECRET_ACCESS_KEY=xxx +# ══ MinIO(open-im-server,Docker 容器 dev-minio)═════════════════ +MINIO_ROOT_USER=minioadmin +MINIO_ROOT_PASSWORD=xxx +MINIO_BUCKET=openim +MINIO_API_PORT=9000 +MINIO_CONSOLE_PORT=9001 +MINIO_INTERNAL_ADDRESS=127.0.0.1:9000 +# 外网访问地址(与 DEPLOY_TEST_IP 一致),须安全组放行 TCP MINIO_API_PORT +MINIO_EXTERNAL_ADDRESS=http://54.116.29.247:9000 +MINIO_PUBLIC_READ=true +# ══ Amazon S3(build-server APK 存储,仍用云端)═════════════════ BUILD_AWS_REGION=ap-east-1 BUILD_AWS_BUCKET=im-hk-apk BUILD_AWS_ACCESS_KEY=xxx BUILD_AWS_SECRET_KEY=xxx -# ══ Docker Redis / Kafka / Etcd ════════════════════════════════ +# ══ Docker Redis / Kafka / Etcd / MinIO ═════════════════════════ REDIS_PORT=6379 REDIS_PASSWORD=openIM123 KAFKA_PORT=9092 @@ -249,6 +255,7 @@ TENCENT_SDK_SECRET_KEY=xxx | Redis | :6379 | | Kafka | 本机服务:`127.0.0.1:9092`(INTERNAL);外网客户端:`DEPLOY_TEST_IP:9094`(EXTERNAL,PLAINTEXT,默认 `KAFKA_EXTERNAL_PORT=9094`) | | Etcd | :2379 | +| MinIO | API `:9000`(映射 `MINIO_API_PORT`);Console `:9001`;外网客户端使用 `MINIO_EXTERNAL_ADDRESS`(须安全组放行 TCP) | | LiveKit | :7880 (API) / :7882 (TCP) / :50000-51000/udp (WebRTC) | > **Kafka 外网**:`03-start-infra.sh` 使用双 listener。云主机安全组需放行 **TCP `KAFKA_EXTERNAL_PORT`**(默认 9094)。仅本机跑后端时仍连 `127.0.0.1:9092` 即可。**若曾用旧脚本建过 `dev-kafka` 单 listener,需** `docker rm -f dev-kafka` **并删除** `.deploy-test/docker-data/kafka` **后重新执行** `03-start-infra.sh`(或 `remove-infra.sh`)以应用新配置。公网 PLAINTEXT 无加密,生产请配合 VPN 或 SASL。 @@ -263,6 +270,7 @@ TENCENT_SDK_SECRET_KEY=xxx 测试服务器(DEPLOY_TEST_IP: 54.116.29.247) │ ├── dev-redis :6379 ←── dev-livekit 通过 host.docker.internal 访问 +├── dev-minio :9000(API):9001(Console)←── 公网访问 DEPLOY_TEST_IP:9000 └── dev-livekit :7880 → HTTP API(后端连接) :7882/tcp+udp → WebRTC fallback @@ -285,6 +293,7 @@ TENCENT_SDK_SECRET_KEY=xxx ├── redis/ ├── kafka/ ├── etcd/ + ├── minio/ └── livekit/ ``` @@ -342,14 +351,14 @@ TENCENT_SDK_SECRET_KEY=xxx cd pc && rm -rf node_modules && yarn install ``` -### `check-conn.sh`(MongoDB / S3) +### `check-conn.sh`(MongoDB / MinIO / S3) -按 `.env.deploy-test` 检查远程 MongoDB 与两个 S3 Bucket。 +按 `.env.deploy-test` 检查远程 MongoDB、本机 **MinIO**(`--endpoint-url http://127.0.0.1:MINIO_API_PORT`)与 build-server 的 **S3** Bucket。 | 项目 | 说明 | |------|------| -| **完整校验** | **mongosh** 可测 MongoDB;S3 用 **`aws s3api head-bucket`** 判断访问,成功后再 `s3 ls` 仅作预览(避免旧版 `ls \| head` 因管道 SIGPIPE 误判失败)。 | -| **未安装工具时** | MongoDB 可用 **nc** 仅测端口连通;S3 会跳过并打印手动验证命令。 | +| **完整校验** | **mongosh** 可测 MongoDB;MinIO/S3 用 **`aws s3api head-bucket`** 判断访问,成功后再 `s3 ls` 仅作预览(避免旧版 `ls \| head` 因管道 SIGPIPE 误判失败)。 | +| **未安装工具时** | MongoDB 可用 **nc** 仅测端口连通;MinIO/S3 会跳过并打印手动验证命令。 | | **安装提示** | 脚本按系统给出命令(macOS 为 `brew`;Amazon/RHEL 为 `dnf`/`yum`),不会在 Linux 上误导为 `brew`。 | | **Ubuntu/Debian 与 mongosh** | 默认 apt **没有** `mongodb-mongosh` 包(`Unable to locate package` 属正常)。需 [MongoDB 官方文档](https://www.mongodb.com/docs/mongodb-shell/install/) 添加 apt 源后再安装,或使用 `snap install mongosh`。 | | **可选自动安装** | **root** 且 `CHECK_CONN_AUTO_INSTALL=1`:**mongosh** 依次默认 apt、snap、MongoDB 8.0 源。**aws** 先 `apt install awscli` / `dnf`/`yum` 装 `aws-cli`;若无包或失败再下载 **AWS CLI v2 官方 zip** 安装(需 `curl`/`unzip` 与联网)。 | diff --git a/check-conn.sh b/check-conn.sh index 6c7c59c..52ee53c 100755 --- a/check-conn.sh +++ b/check-conn.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash # ============================================================================= -# check-conn.sh — 验证远程服务连接(MongoDB 和 Amazon S3) +# check-conn.sh — 验证远程服务连接(MongoDB、MinIO、build-server S3) # # 用法: -# ./check-conn.sh # 同时检查 MongoDB 和 S3 +# ./check-conn.sh # 同时检查 MongoDB 与对象存储 # ./check-conn.sh mongo # 只检查 MongoDB -# ./check-conn.sh s3 # 只检查 S3 +# ./check-conn.sh s3 # 只检查 MinIO(openim)与 S3(build) # # 环境: # CHECK_CONN_AUTO_INSTALL=1 以 root 运行时尝试用 apt/dnf/yum 安装 awscli、mongosh(可选) @@ -238,7 +238,7 @@ _check_s3_bucket() { echo "" if [[ "${key_id}" == "YOUR_"* || -z "${key_id}" ]]; then - error "S3 AccessKeyID 未配置,请编辑 .env.deploy-test" + error "AccessKeyID 未配置,请编辑 .env.deploy-test" return 1 fi @@ -299,14 +299,14 @@ _check_s3_bucket() { check_s3() { _try_install_awscli - step "S3 (open-im-server) — IM 文件存储" + step "MinIO (open-im-server) — IM 文件存储(Docker dev-minio)" _check_s3_bucket \ "openim" \ - "${OPENIM_AWS_ACCESS_KEY_ID}" \ - "${OPENIM_AWS_SECRET_ACCESS_KEY}" \ - "${OPENIM_AWS_REGION}" \ - "${OPENIM_AWS_BUCKET}" \ - "${OPENIM_AWS_ENDPOINT:-}" + "${MINIO_ROOT_USER}" \ + "${MINIO_ROOT_PASSWORD}" \ + "us-east-1" \ + "${MINIO_BUCKET}" \ + "http://127.0.0.1:${MINIO_API_PORT:-9000}" echo "" step "S3 (build-server) — App APK/IPA 构建产物" diff --git a/logs.sh b/logs.sh index 0bbfb56..112d40d 100755 --- a/logs.sh +++ b/logs.sh @@ -141,6 +141,7 @@ case "$SVC" in redis) _docker_log "dev-redis"; exit 0 ;; kafka) _docker_log "dev-kafka"; exit 0 ;; etcd) _docker_log "dev-etcd"; exit 0 ;; + minio) _docker_log "dev-minio"; exit 0 ;; livekit) _docker_log "dev-livekit"; exit 0 ;; esac diff --git a/remove-infra.sh b/remove-infra.sh index 30bfa60..1b9fdca 100755 --- a/remove-infra.sh +++ b/remove-infra.sh @@ -14,7 +14,7 @@ step "删除 Docker 基础设施容器及数据" echo "" warn "⚠️ 此操作将删除以下内容:" - echo " 容器: dev-livekit, dev-redis, dev-kafka, dev-etcd" + echo " 容器: dev-livekit, dev-minio, dev-redis, dev-kafka, dev-etcd" echo " 数据: $DATA_DIR/" echo "" read -p "确认删除?(输入 yes 继续): " -r CONFIRM @@ -24,7 +24,7 @@ if [[ "$CONFIRM" != "yes" ]]; then fi echo "" - for cname in dev-livekit dev-redis dev-kafka dev-etcd; do + for cname in dev-livekit dev-minio dev-redis dev-kafka dev-etcd; do if docker ps -a --format '{{.Names}}' | grep -q "^${cname}$"; then docker rm -f "$cname" > /dev/null && success "已删除容器: $cname" else diff --git a/restart.sh b/restart.sh index 5d884fd..6f01ca0 100755 --- a/restart.sh +++ b/restart.sh @@ -90,13 +90,14 @@ case "$SVC" in redis) _restart_docker "Redis" "dev-redis"; exit 0 ;; kafka) _restart_docker "Kafka" "dev-kafka"; exit 0 ;; etcd) _restart_docker "Etcd" "dev-etcd"; exit 0 ;; + minio) _restart_docker "MinIO" "dev-minio"; exit 0 ;; esac # ── 处理后端服务 ────────────────────────────────────────────────────────────── if [[ -z "${svc_workdir[$SVC]:-}" ]]; then error "未知服务: $SVC" echo "后端服务: ${!svc_workdir[*]}" - echo "Docker: redis, kafka, etcd" + echo "Docker: redis, kafka, etcd, minio" exit 1 fi diff --git a/setup.sh b/setup.sh index 252f46d..3d53277 100755 --- a/setup.sh +++ b/setup.sh @@ -22,7 +22,7 @@ header "一键完整部署(首次使用)" echo -e "${BOLD}基础设施策略:${NC}" echo " Redis / Kafka / Etcd → Docker 容器(本地)" echo " MongoDB → 远程服务" -echo " 文件存储 → Amazon S3" +echo " 文件存储 → MinIO(Docker dev-minio)" echo "" # ── 步骤 1:初始化 .env.local ───────────────────────────────────────────────── @@ -30,7 +30,7 @@ step "[1/5] 初始化 .env.local" bash "$SCRIPT_DIR/01-init-env.sh" echo "" -warn "请确认 .env.local 中的 MongoDB 和 AWS S3 配置已正确填写!" +warn "请确认 .env.deploy-test 中的 MongoDB 和 MinIO(MINIO_*)配置已正确填写!" echo -e " ${CYAN}vim $ENV_FILE${NC}" echo "" read -p "配置已填写好,继续执行?(y/N): " -n 1 -r REPLY; echo @@ -79,7 +79,7 @@ echo " ./deploy-test/status.sh # 查看全部状态" echo " ./deploy-test/logs.sh # 实时日志" echo " ./deploy-test/restart.sh # 重启服务" echo " ./deploy-test/restart.sh --build # 重编译并重启" -echo " ./deploy-test/check-conn.sh # 验证 MongoDB/S3" +echo " ./deploy-test/check-conn.sh # 验证 MongoDB / MinIO" echo "" echo -e "${BOLD}停止服务:${NC}" echo " ./deploy-test/stop.sh # 停止后端进程" diff --git a/status.sh b/status.sh index f16fbee..bf294d6 100755 --- a/status.sh +++ b/status.sh @@ -20,6 +20,7 @@ print_container_status "Redis" "dev-redis" "${REDIS_PORT:-6379}" print_container_status "Kafka" "dev-kafka" "${KAFKA_PORT:-9092}" printf " ${CYAN}◉${NC} %-10s Kafka 外网 bootstrap(EXTERNAL)%s:%s TCP PLAINTEXT\n" "" "${DEPLOY_TEST_IP:-?}" "${KAFKA_EXTERNAL_PORT:-9094}" print_container_status "Etcd" "dev-etcd" "${ETCD_PORT:-2379}" +print_container_status "MinIO" "dev-minio" "${MINIO_API_PORT:-9000}" print_container_status "LiveKit" "dev-livekit" "7880" printf " ${CYAN}◉${NC} %-10s 公网 %s:50000-51000/udp (WebRTC)\n" "" "${LIVEKIT_NODE_IP:-?}" @@ -28,8 +29,8 @@ echo "" echo -e "${BOLD}[ 远程服务(连接配置)]${NC}" printf " ${CYAN}◉${NC} %-10s %s\n" "MongoDB" \ "${MONGO_HOST:-?}:${MONGO_PORT:-27017}/${MONGO_DATABASE:-?} (authSource=${MONGO_AUTHSOURCE:-?})" -printf " ${CYAN}◉${NC} %-10s %s\n" "S3" \ - "s3://${AWS_BUCKET:-?} region=${AWS_REGION:-?}" +printf " ${CYAN}◉${NC} %-10s %s\n" "MinIO" \ + "bucket=${MINIO_BUCKET:-?} external=${MINIO_EXTERNAL_ADDRESS:-?}" # ── 后端服务 ───────────────────────────────────────────────────────────────── echo "" diff --git a/stop-infra.sh b/stop-infra.sh index 9ad2d27..16895a0 100755 --- a/stop-infra.sh +++ b/stop-infra.sh @@ -3,7 +3,7 @@ # stop-infra.sh — 停止 Docker 基础设施容器 # # 用法: -# ./stop-infra.sh # 停止 Redis / Kafka / Etcd +# ./stop-infra.sh # 停止 Redis / Kafka / Etcd / MinIO / LiveKit # ./stop-infra.sh redis # 只停止 Redis # ./stop-infra.sh kafka # 只停止 Kafka # ./stop-infra.sh etcd # 只停止 Etcd @@ -33,6 +33,7 @@ case "$TARGET" in step "停止所有 Docker 基础设施" _stop_container "LiveKit" "dev-livekit" _stop_container "Kafka" "dev-kafka" + _stop_container "MinIO" "dev-minio" _stop_container "Redis" "dev-redis" _stop_container "Etcd" "dev-etcd" echo "" @@ -43,9 +44,10 @@ case "$TARGET" in kafka) _stop_container "Kafka" "dev-kafka" ;; etcd) _stop_container "Etcd" "dev-etcd" ;; livekit) _stop_container "LiveKit" "dev-livekit" ;; + minio) _stop_container "MinIO" "dev-minio" ;; *) error "未知组件: $TARGET" - echo "可用: redis, kafka, etcd, livekit, all" + echo "可用: redis, kafka, etcd, minio, livekit, all" exit 1 ;; esac