You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

136 lines
5.0 KiB

#!/usr/bin/env bash
# yunyan-sas 多环境部署入口
# local —— 本机 docker compose
# dev / prod —— SSH 同步配置到目标机后远程 docker compose
#
# 配置来源:
# env/<环境>.env 运行时变量(镜像/网络/DB/Redis/NATS/Console 等)
# targets/<环境>.conf 远程目标(SSH 主机/密钥/部署目录/镜像仓库账号)
set -euo pipefail
ROOT="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$ROOT/.." && pwd)"
ENV="${1:-}"
ACTION="${2:-}"
green() { printf "\033[32m%s\033[0m\n" "$*"; }
blue() { printf "\033[34m%s\033[0m\n" "$*"; }
red() { printf "\033[31m%s\033[0m\n" "$*"; }
usage() {
cat <<'EOF'
用法: ./deploy.sh <环境> <操作>
环境: local | dev | prod
操作:
up 启动(local 直接起;dev/prod 同步配置后远程起)
down 停止并移除容器
pull 拉取最新镜像
restart 重启容器
logs 跟随日志
ps 查看容器状态
build 构建并推送镜像到私有仓库(调用 ../build.sh,TAG 取自 env)
deploy 一键发布:build + 同步配置 + 远程 pull + up
示例:
./deploy.sh local up # 本机起服务
./deploy.sh dev build # 构建推送 dev 镜像
./deploy.sh dev deploy # 一键发布到开发服务器
./deploy.sh prod deploy # 一键发布到生产服务器
./deploy.sh prod logs # 跟随生产日志
EOF
}
[ -z "$ENV" ] && { usage; exit 1; }
case "$ENV" in local|dev|prod) ;; *) red "✗ 未知环境: $ENV"; usage; exit 1 ;; esac
[ -z "$ACTION" ] && { usage; exit 1; }
ENV_FILE="$ROOT/env/$ENV.env"
[ -f "$ENV_FILE" ] || { red "✗ 缺少环境变量文件: deploy/env/$ENV.env(参考 env/example.env)"; exit 1; }
# 从 env 取某个 key 的值
env_val() { grep -E "^$1=" "$ENV_FILE" | head -1 | cut -d= -f2-; }
TAG="$(env_val TAG)"; TAG="${TAG:-latest}"
# ── 构建并推送镜像(复用根目录 build.sh)──
do_build() {
blue ">>> [$ENV] 构建并推送镜像 (TAG=$TAG)"
TAG="$TAG" "$REPO_ROOT/build.sh" all
}
# ── 本机 compose ──
local_compose() {
cp "$ENV_FILE" "$ROOT/.env"
( cd "$ROOT" && docker compose --env-file "$ROOT/.env" "$@" )
}
local_ensure_network() {
local net; net="$(env_val DOCKER_NETWORK)"; net="${net:-1panel-network}"
docker network inspect "$net" >/dev/null 2>&1 || docker network create "$net"
}
# ── 远程目标 ──
load_target() {
local conf="$ROOT/targets/$ENV.conf"
[ -f "$conf" ] || { red "✗ 缺少部署目标: deploy/targets/$ENV.conf(参考 targets/example.conf)"; exit 1; }
# shellcheck disable=SC1090
source "$conf"
[ -z "${SSH_HOST:-}" ] && { red "✗ targets/$ENV.conf 未配置 SSH_HOST"; exit 1; }
[ -z "${REMOTE_DIR:-}" ] && { red "✗ targets/$ENV.conf 未配置 REMOTE_DIR"; exit 1; }
local port="${SSH_PORT:-22}"
local key="${SSH_KEY/#\~/$HOME}"
local common="-i $key -o StrictHostKeyChecking=accept-new"
SSH="ssh -p $port $common ${SSH_USER}@${SSH_HOST}"
SCP="scp -P $port $common"
}
remote_sync() {
blue ">>> [$ENV] 同步配置到 ${SSH_USER}@${SSH_HOST}:${REMOTE_DIR}"
$SSH "mkdir -p '$REMOTE_DIR/console/confs' '$REMOTE_DIR/console/log'"
$SCP "$ROOT/docker-compose.yml" "${SSH_USER}@${SSH_HOST}:$REMOTE_DIR/docker-compose.yml"
$SCP "$ENV_FILE" "${SSH_USER}@${SSH_HOST}:$REMOTE_DIR/.env"
$SCP "$ROOT/console/confs/console.yaml" "${SSH_USER}@${SSH_HOST}:$REMOTE_DIR/console/confs/console.yaml"
}
remote_ensure_network() {
local net; net="$(env_val DOCKER_NETWORK)"; net="${net:-1panel-network}"
$SSH "docker network inspect '$net' >/dev/null 2>&1 || docker network create '$net'"
}
remote_login() {
[ -n "${REGISTRY_PASS:-}" ] && \
$SSH "docker login '${REGISTRY:-docker-registry.ideapsound.com}' -u '${REGISTRY_USER:-admin}' -p '$REGISTRY_PASS'"
}
remote_compose() { $SSH "cd '$REMOTE_DIR' && docker compose --env-file .env $*"; }
# ================= 分发 =================
if [ "$ENV" = "local" ]; then
case "$ACTION" in
up) local_ensure_network; local_compose up -d ;;
down) local_compose down ;;
pull) local_compose pull ;;
restart) local_compose restart ;;
logs) local_compose logs -f --tail=120 ;;
ps) local_compose ps ;;
build) do_build ;;
deploy) do_build; local_ensure_network; local_compose pull; local_compose up -d ;;
*) red "✗ 未知操作: $ACTION"; usage; exit 1 ;;
esac
else
load_target
case "$ACTION" in
up) remote_sync; remote_ensure_network; remote_login; remote_compose pull; remote_compose up -d ;;
down) remote_compose down ;;
pull) remote_login; remote_compose pull ;;
restart) remote_compose restart ;;
logs) remote_compose logs -f --tail=120 ;;
ps) remote_compose ps ;;
build) do_build ;;
deploy) do_build; remote_sync; remote_ensure_network; remote_login; remote_compose pull; remote_compose up -d ;;
*) red "✗ 未知操作: $ACTION"; usage; exit 1 ;;
esac
fi
green "✓ [$ENV] $ACTION 完成"