#!/usr/bin/env bash # voitrans 开发环境:一键「构建开发镜像 → 推送 → 更新开发环境」。 # # 业务五服务(gateway/home/api/mcp/timer)打成单镜像 voitrans-a11,推到私有仓库后远端拉取重启。 # # 用法(在 deploy/voitrans/ 下): # ./dev-deploy.sh # 构建并发布 voitrans-a11:dev-latest # # 开发版镜像始终使用固定 tag dev-latest(不接受参数覆盖),每次构建覆盖同一 tag。 set -euo pipefail SVC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # deploy/voitrans REPO_ROOT="$(cd "$SVC_DIR/../.." && pwd)" # 仓库根 BUILD_CONTEXT="$REPO_ROOT/apps/services" # Go 构建上下文 DOCKERFILE="$BUILD_CONTEXT/Dockerfile.voitrans" blue() { printf "\033[34m%s\033[0m\n" "$*"; } green() { printf "\033[32m%s\033[0m\n" "$*"; } red() { printf "\033[31m%s\033[0m\n" "$*"; } # ╔══════════════════════════════════════════════════════════════════════╗ # ║ 开发部署目标 / 私有仓库凭据 —— 写死在此(本文件纳入 git,私有仓库内可接受) ║ # ║ ⚠️ 公开仓库前务必清空 DEV_HOST / REGISTRY_PASS ║ # ╚══════════════════════════════════════════════════════════════════════╝ IMAGE_NAME="voitrans-a11" # 业务单镜像名 REGISTRY="docker-registry.ideapsound.com" # 私有镜像仓库 REGISTRY_USER="admin" # 仓库账号 REGISTRY_PASS="li13451234" # 仓库密码 DEV_HOST="124.222.232.218" # ← 开发服务器 IP(必填) DEV_PORT=22 DEV_USER=root DEV_KEY=/Users/liwei/Documents/key/earphone.pem # 本机访问开发服务器的 SSH 私钥 DEV_DIR="/home/work/voitrans-a11" # 远端部署目录 PLATFORM="${PLATFORM:-linux/amd64}" TAG="dev-latest" # 开发版固定 tag,每次构建覆盖同一 dev-latest ENV_FILE="$SVC_DIR/env/dev.env" FULL_IMAGE="$REGISTRY/$IMAGE_NAME:$TAG" [ -f "$DOCKERFILE" ] || { red "✗ 缺少 $DOCKERFILE"; exit 1; } [ -f "$ENV_FILE" ] || { red "✗ 缺少 env/dev.env(先 cp env/dev.env.example env/dev.env 并填写)"; exit 1; } : "${DEV_HOST:?请在 dev-deploy.sh 顶部填 DEV_HOST(开发服务器 IP)}" # 生成 compose/容器用 .env = dev.env(去掉 TAG/REGISTRY) + 注入 REGISTRY + 本次 TAG gen_env() { { grep -vE '^(REGISTRY|TAG)=' "$ENV_FILE" || true; } > "$SVC_DIR/.env" { printf 'REGISTRY=%s\n' "$REGISTRY" printf 'TAG=%s\n' "$TAG" } >> "$SVC_DIR/.env" } # ── 远程 SSH 基础 ── _ssh() { ssh -p "$DEV_PORT" -i "${DEV_KEY/#\~/$HOME}" -o StrictHostKeyChecking=accept-new "$DEV_USER@$DEV_HOST" "$@"; } _scp() { scp -P "$DEV_PORT" -i "${DEV_KEY/#\~/$HOME}" -o StrictHostKeyChecking=accept-new "$@"; } _dest() { echo "$DEV_USER@$DEV_HOST:$1"; } # 1) 构建并推送镜像 blue ">>> 构建镜像 $FULL_IMAGE (context=$BUILD_CONTEXT)" echo "$REGISTRY_PASS" | docker login "$REGISTRY" -u "$REGISTRY_USER" --password-stdin docker build --network=host --platform "$PLATFORM" -f "$DOCKERFILE" -t "$FULL_IMAGE" "$BUILD_CONTEXT" docker push "$FULL_IMAGE" # 2) 同步配置并远端拉起 : "${DEV_HOST:?请在 dev-deploy.sh 顶部填 DEV_HOST}" gen_env blue ">>> 同步配置到 $DEV_USER@$DEV_HOST:$DEV_DIR" _ssh "mkdir -p '$DEV_DIR/confs' '$DEV_DIR/log'" _scp "$SVC_DIR/docker-compose.yml" "$(_dest "$DEV_DIR/docker-compose.yml")" _scp "$SVC_DIR/.env" "$(_dest "$DEV_DIR/.env")" _scp -r "$SVC_DIR/confs/." "$(_dest "$DEV_DIR/confs/")" blue ">>> 远端拉取并重启" _ssh "echo '$REGISTRY_PASS' | docker login '$REGISTRY' -u '$REGISTRY_USER' --password-stdin >/dev/null" _ssh "docker network inspect 1panel-network >/dev/null 2>&1 || docker network create 1panel-network" _ssh "cd '$DEV_DIR' && docker compose --env-file .env pull && docker compose --env-file .env up -d && docker image prune -f" green "✓ voitrans dev 已发布: $FULL_IMAGE → $DEV_HOST:$DEV_DIR"