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
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 完成"
|
|
|