Files
deploy-test/03-start-infra.sh
2026-04-13 01:27:34 +07:00

228 lines
9.5 KiB
Bash
Executable File
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
# =============================================================================
# 03-start-infra.sh — 启动 Docker 基础设施Redis / Kafka / Etcd / LiveKit
#
# 数据目录: .local-dev/docker-data/<svc>/
# 容器日志: .local-dev/docker-logs/<svc>/<svc>-YYYYMMDD.log每日一文件
# 脚本日志: .local-dev/script-logs/03-start-infra-<ts>.log
#
# 后续步骤04-build.sh编译后端服务
# =============================================================================
set -euo pipefail
source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh"
load_env
init_dirs
init_script_log # ← 脚本执行日志
require_docker_running
# Docker 日志驱动公共参数JSON 文件,最多 5 个 50MB 轮转)
LOG_OPTS=(
--log-driver json-file
--log-opt max-size=50m
--log-opt max-file=5
)
header "步骤 3 / 5 — 启动 Docker 基础设施"
# ──────────────────────────────────────────────────────────────────────────────
# Redis
# ──────────────────────────────────────────────────────────────────────────────
step "Redis"
if docker ps --format '{{.Names}}' | grep -q '^dev-redis$'; then
success "Redis 已在运行 (container=dev-redis) :${REDIS_PORT}"
elif docker ps -a --format '{{.Names}}' | grep -q '^dev-redis$'; then
info "重新启动已有容器 dev-redis..."
docker start dev-redis > /dev/null
success "Redis 已启动 :${REDIS_PORT}"
else
info "创建并启动 Redis 容器..."
docker run -d \
--name dev-redis \
--restart unless-stopped \
-p "${REDIS_PORT}:6379" \
-v "${DATA_DIR}/redis:/data" \
"${LOG_OPTS[@]}" \
redis:7-alpine \
redis-server --requirepass "${REDIS_PASSWORD:-openIM123}" --appendonly yes \
> /dev/null
success "Redis 容器已创建并启动 :${REDIS_PORT} (密码: ${REDIS_PASSWORD:-openIM123})"
fi
sleep 1
if docker exec dev-redis redis-cli -a "${REDIS_PASSWORD:-openIM123}" ping 2>/dev/null | grep -q PONG; then
success "Redis 连通性: PONG ✓"
else
warn "Redis 未响应 PING请查看日志: ./deploy-test/logs.sh redis"
fi
start_docker_logger "dev-redis"
# ──────────────────────────────────────────────────────────────────────────────
# KafkaKRaft 模式)
# ──────────────────────────────────────────────────────────────────────────────
step "Kafka (KRaft)"
if docker ps --format '{{.Names}}' | grep -q '^dev-kafka$'; then
success "Kafka 已在运行 (container=dev-kafka) :${KAFKA_PORT}"
elif docker ps -a --format '{{.Names}}' | grep -q '^dev-kafka$'; then
info "重新启动已有容器 dev-kafka..."
docker start dev-kafka > /dev/null
info "等待 Kafka 就绪 (8s)..."
sleep 8
success "Kafka 已启动 :${KAFKA_PORT}"
else
info "创建并启动 Kafka 容器(首次拉取镜像可能较慢)..."
KAFKA_CLUSTER_ID="MkU3OEVBNTcwNTJENDM2Qk"
docker run -d \
--name dev-kafka \
--restart unless-stopped \
-p "${KAFKA_PORT}:9092" \
-v "${DATA_DIR}/kafka:/bitnami/kafka" \
-e KAFKA_CFG_NODE_ID=0 \
-e KAFKA_CFG_PROCESS_ROLES=controller,broker \
-e KAFKA_CFG_LISTENERS="PLAINTEXT://:9092,CONTROLLER://:9093" \
-e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP="CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT" \
-e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS="0@localhost:9093" \
-e KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER \
-e KAFKA_CFG_ADVERTISED_LISTENERS="PLAINTEXT://127.0.0.1:${KAFKA_PORT}" \
-e KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true \
-e KAFKA_KRAFT_CLUSTER_ID="$KAFKA_CLUSTER_ID" \
"${LOG_OPTS[@]}" \
bitnami/kafka:3.7 \
> /dev/null
info "等待 Kafka 就绪 (15s)..."
sleep 15
success "Kafka 容器已创建并启动 :${KAFKA_PORT}"
fi
start_docker_logger "dev-kafka"
# 初始化必要 Topics
step "Kafka Topics 初始化"
TOPICS=(toRedis toMongo toPush toOfflinePush)
for topic in "${TOPICS[@]}"; do
if docker exec dev-kafka kafka-topics.sh \
--bootstrap-server localhost:9092 \
--list 2>/dev/null | grep -q "^${topic}$"; then
info " topic 已存在: $topic"
else
docker exec dev-kafka kafka-topics.sh \
--create \
--topic "$topic" \
--bootstrap-server localhost:9092 \
--partitions 8 \
--replication-factor 1 \
2>/dev/null \
&& success " ✓ 创建 topic: $topic" \
|| warn " ✗ 创建失败: $topicKafka 未就绪,重试: ./deploy-test/03-start-infra.sh"
fi
done
# ──────────────────────────────────────────────────────────────────────────────
# Etcd
# ──────────────────────────────────────────────────────────────────────────────
step "Etcd"
if docker ps --format '{{.Names}}' | grep -q '^dev-etcd$'; then
success "Etcd 已在运行 (container=dev-etcd) :${ETCD_PORT}"
elif docker ps -a --format '{{.Names}}' | grep -q '^dev-etcd$'; then
info "重新启动已有容器 dev-etcd..."
docker start dev-etcd > /dev/null
sleep 2
success "Etcd 已启动 :${ETCD_PORT}"
else
info "创建并启动 Etcd 容器..."
docker run -d \
--name dev-etcd \
--restart unless-stopped \
-p "${ETCD_PORT}:2379" \
-v "${DATA_DIR}/etcd:/etcd-data" \
-e ALLOW_NONE_AUTHENTICATION=yes \
-e ETCD_DATA_DIR=/etcd-data \
"${LOG_OPTS[@]}" \
bitnami/etcd:3.5 \
> /dev/null
sleep 2
success "Etcd 容器已创建并启动 :${ETCD_PORT}"
fi
if docker exec dev-etcd etcdctl endpoint health 2>/dev/null | grep -q 'is healthy'; then
success "Etcd 连通性: healthy ✓"
else
warn "Etcd 未返回健康状态,可能仍在启动中"
fi
start_docker_logger "dev-etcd"
# ──────────────────────────────────────────────────────────────────────────────
# LiveKit本地 Docker 容器,复用 dev-redis
# ──────────────────────────────────────────────────────────────────────────────
step "LiveKit"
LK_CONF="$ROOT_DIR/livekit/livekit.yaml"
if [[ ! -f "$LK_CONF" ]]; then
warn "livekit/livekit.yaml 不存在,请先执行: ./deploy-test/02-patch-config.sh"
else
if docker ps --format '{{.Names}}' | grep -q '^dev-livekit$'; then
success "LiveKit 已在运行 (container=dev-livekit) :7880"
elif docker ps -a --format '{{.Names}}' | grep -q '^dev-livekit$'; then
info "重新启动已有容器 dev-livekit..."
docker start dev-livekit > /dev/null
sleep 2
success "LiveKit 已启动 :7880"
else
info "创建并启动 LiveKit 容器(首次拉取镜像需要一点时间)..."
EXTRA_HOSTS=""
[[ "$(uname -s)" == "Linux" ]] && EXTRA_HOSTS="--add-host host.docker.internal:host-gateway"
# shellcheck disable=SC2086
docker run -d \
--name dev-livekit \
--restart unless-stopped \
-p 7880:7880 \
-p 7882:7882/tcp \
-p 7882:7882/udp \
-p 50000-51000:50000-51000/udp \
-v "${LK_CONF}:/etc/livekit.yaml:ro" \
"${LOG_OPTS[@]}" \
$EXTRA_HOSTS \
livekit/livekit-server:latest \
--config /etc/livekit.yaml \
> /dev/null
sleep 3
if docker ps --format '{{.Names}}' | grep -q '^dev-livekit$'; then
success "LiveKit 容器已创建并启动 :7880"
info " 公网 IP: ${LIVEKIT_NODE_IP} (WebRTC 媒体流直连)"
info " API Key: ${LIVEKIT_API_KEY}"
else
error "LiveKit 启动失败,查看日志: ./deploy-test/logs.sh livekit"
fi
fi
start_docker_logger "dev-livekit"
fi
# ──────────────────────────────────────────────────────────────────────────────
# 汇总
# ──────────────────────────────────────────────────────────────────────────────
echo ""
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 "LiveKit" "dev-livekit" "7880"
echo ""
echo -e "${BOLD}日志目录:${NC}"
echo " Docker 容器日志: $DOCKER_LOG_DIR/"
echo " 本脚本执行日志: $_CURRENT_SCRIPT_LOG"
echo ""
echo -e " LiveKit 公网: ${LIVEKIT_NODE_IP}:50000-51000/udp (WebRTC 媒体流)"
echo ""
success "Docker 基础设施已就绪!"
echo ""
echo -e "${BOLD}下一步:${NC}"
echo -e " 编译所有后端 Go 服务:"
echo -e " ${CYAN}./deploy-test/04-build.sh${NC}"