Browse Source
云雁(yunyan)/灵谱(lingpu) 的部署目标从所有脚本移除,ENVS / PROD_ENVS / REGIONS
现在都只剩 along。那 6 台(云雁测试/上海/日本/新加坡、灵谱测试/正式)的 SSH 私钥路径
指向的是另一台开发机,本机一台都登不上(22 端口通、无可用密钥),留在交互菜单里只会误选。
- 删 deploy/{console,admin,app}/dev-deploy.sh 的 lingpu、yunyan 两段 env_profile
- 删 deploy/{console,admin}/prod-deploy.sh 的 yunyan、lingpu 两段
- 删 deploy/app/prod-deploy.sh 的 shanghai/japan/singapore 三段 region_profile
- 删 deploy/admin/deploy.sh:早期脚本,只指向灵谱且生产位留空,已被
dev-deploy/prod-deploy 取代(CLAUDE.md 里"要同步两份 deploy.sh"也是错的,
console 那份早就不存在)
- IP 与私钥路径不再记在文档里,需要时从 git 历史取回
镜像仓库刻意保留:registry.voitrans.net / registry.lingpu.net 都在,prod-build.sh
仍可选 yunyan|lingpu 推镜像(三家仓库本机都能读写,协作者仍从他那台机部署这两家)。
顺带修掉三处把已下线机器地址连明文数据库密码一起写死的测试:
- sys/nats/nats_test.go 有个真 bug——`url := "nats://<写死地址>"` 紧接着 `if url == ""`,
常量永远不为空,所谓"默认跳过"从来没生效:每次 go test 都在连那台早已废弃的机器,
白等 4.5 秒超时。现在真正读 NATS_URL 了。
- modules/{api,echomeet}/model_test.go 的 DSN 改走 API_TEST_DSN / ECHOMEET_TEST_DSN
另外给 app/prod-deploy.sh 加了一条明确报错:输入已移除的区域名(如 shanghai)原本会被
is_tag_like 当成版本号,报出"版本指定了两次"这种驴唇不对马嘴的错。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
main
18 changed files with 138 additions and 426 deletions
@ -1,184 +0,0 @@ |
|||
#!/usr/bin/env bash |
|||
# <服务> 部署脚本(每个服务目录各一份,服务名取自所在目录名) |
|||
# |
|||
# 用法: ./deploy.sh <env> [action] (在 deploy/<服务>/ 下运行) |
|||
# env : local | dev | prod |
|||
# action : dev/prod → deploy(默认) | up | build | pull | down | restart | logs | ps |
|||
# local → up(默认) | build | pull | down | restart | logs | ps |
|||
# |
|||
# deploy = 构建推送镜像 + 同步配置 + 远程 pull + up(一键发布,仅 dev/prod) |
|||
# up = 远程:仅同步配置 + 远程 pull + up(用已推送镜像);本机:起容器 |
|||
# |
|||
# 例(在 deploy/console/ 下): |
|||
# ./deploy.sh prod # 一键发布生产 console |
|||
# ./deploy.sh prod logs # 看生产 console 日志 |
|||
# ./deploy.sh local up # 本机起 console |
|||
# ./deploy.sh dev build # 只构建推送 dev 镜像 |
|||
set -euo pipefail |
|||
|
|||
SVC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 本服务部署目录(deploy/<服务>) |
|||
SERVICE="$(basename "$SVC_DIR")" # 服务名 = 目录名(console / admin) |
|||
REPO_ROOT="$(cd "$SVC_DIR/../.." && pwd)" # 仓库根(deploy/<服务>/../..) |
|||
|
|||
blue() { printf "\033[34m%s\033[0m\n" "$*"; } |
|||
green() { printf "\033[32m%s\033[0m\n" "$*"; } |
|||
red() { printf "\033[31m%s\033[0m\n" "$*"; } |
|||
|
|||
# ╔══════════════════════════════════════════════════════════════════════╗ |
|||
# ║ 部署目标 / 私有仓库配置 —— 写死在这里,改这里即可(按环境) ║ |
|||
# ║ console、admin 同机不同目录;DEPLOY_DIR 自动 = /opt/yunyan/<服务名> ║ |
|||
# ║ 注意:本文件纳入 git,下面的密码/IP 会随仓库提交(私有仓库内可接受) ║ |
|||
# ╚══════════════════════════════════════════════════════════════════════╝ |
|||
deploy_profile() { |
|||
DEPLOY_HOST=""; REGISTRY_PASS="" # 占位,local 用不到;dev/prod 在下面填 |
|||
# —— 各环境通用默认 —— |
|||
REGISTRY=registry.voitrans.net # 私有镜像仓库地址 |
|||
REGISTRY_USER=liwei # 仓库账号 |
|||
DEPLOY_PORT=22 # 服务器 SSH 端口 |
|||
DEPLOY_USER=root # 服务器 SSH 用户 |
|||
DEPLOY_KEY=~/Documents/灵谱/lingpu-hk.pem # 本机访问服务器的 SSH 私钥路径 |
|||
case "$ENV_NAME" in |
|||
dev) |
|||
DEPLOY_HOST="8.217.193.140" # 灵谱香港阿里云(lingpu-hk) |
|||
REGISTRY_PASS="li13451234" # 私有仓库密码(liwei 用户) |
|||
;; |
|||
prod) |
|||
DEPLOY_HOST="" # ← 生产服务器 IP(必填) |
|||
REGISTRY_PASS="" # ← 私有仓库密码(必填) |
|||
;; |
|||
local) ;; # 本机不走 SSH,无需填 |
|||
esac |
|||
DEPLOY_DIR="/home/work/starpivot-$SERVICE" # 远程部署目录(与 /home/work 下其余服务一致) |
|||
} |
|||
|
|||
usage() { |
|||
cat >&2 <<EOF |
|||
用法: ./deploy.sh <env> [action] (在 deploy/$SERVICE/ 下运行) |
|||
env : local | dev | prod |
|||
action : dev/prod → deploy(默认) | up | build | pull | down | restart | logs | ps |
|||
local → up(默认) | build | pull | down | restart | logs | ps |
|||
例: |
|||
./deploy.sh prod # 一键发布生产 $SERVICE |
|||
./deploy.sh prod logs # 看生产 $SERVICE 日志 |
|||
./deploy.sh local up # 本机起 $SERVICE |
|||
./deploy.sh dev build # 只构建推送 dev 镜像 |
|||
EOF |
|||
exit 1 |
|||
} |
|||
|
|||
# ── 参数解析与校验 ── |
|||
ENV_NAME="${1:-}"; ACTION="${2:-}" |
|||
[ -n "$ENV_NAME" ] || usage |
|||
[ -f "$SVC_DIR/docker-compose.yml" ] || { red "✗ $SERVICE 目录缺 docker-compose.yml(deploy.sh 须放在服务目录内)"; exit 1; } |
|||
case "$ENV_NAME" in |
|||
local|dev|prod) ;; |
|||
*) red "✗ 未知环境: ${ENV_NAME}(应为 local|dev|prod)"; usage ;; |
|||
esac |
|||
# 默认动作:远程发布默认 deploy,本机默认 up |
|||
[ -n "$ACTION" ] || { [ "$ENV_NAME" = local ] && ACTION=up || ACTION=deploy; } |
|||
|
|||
# 从 ENV_FILE 安全读取单个变量值(去除可能的外层双引号) |
|||
_envget() { |
|||
{ grep -E "^$1=" "$ENV_FILE" || true; } | head -1 | cut -d= -f2- | sed -e 's/^"//' -e 's/"$//' |
|||
} |
|||
|
|||
# 载入 env/<环境>.env —— 现在只放容器运行时配置(DSN / Redis / NATS / 密钥 / 端口 / TAG / 网络)。 |
|||
# 部署目标与仓库凭据已写死在 deploy_profile,不再放 env 文件。脚本只需从这里取 compose 仍要的 TAG/网络。 |
|||
load_env() { |
|||
ENV_FILE="$SVC_DIR/env/$ENV_NAME.env" |
|||
if [ ! -f "$ENV_FILE" ]; then |
|||
red "✗ 缺少 $SERVICE/env/$ENV_NAME.env —— 请先从 $SERVICE/env/$ENV_NAME.env.example 复制并填写" |
|||
exit 1 |
|||
fi |
|||
TAG="$(_envget TAG)"; TAG="${TAG:-latest}" |
|||
DOCKER_NETWORK="$(_envget DOCKER_NETWORK)"; DOCKER_NETWORK="${DOCKER_NETWORK:-1panel-network}" |
|||
} |
|||
|
|||
# 生成 compose 用 .env = 服务运行时 env 文件 + 注入写死的 REGISTRY(镜像地址替换用) |
|||
# 先滤掉源文件里可能残留的 REGISTRY 行,保证唯一、不依赖 compose 的覆盖顺序。 |
|||
gen_env() { |
|||
{ grep -v '^REGISTRY=' "$ENV_FILE" || true; } > "$SVC_DIR/.env" |
|||
printf 'REGISTRY=%s\n' "$REGISTRY" >> "$SVC_DIR/.env" |
|||
} |
|||
|
|||
# 构建并推送本服务镜像(复用仓库根目录 build.sh,目标 = 服务名)。 |
|||
# local 环境只构建不推送(PUSH=0),dev/prod 构建并推送到私有仓库。 |
|||
build_push() { |
|||
local push=1; [ "$ENV_NAME" = local ] && push=0 |
|||
blue ">>> 构建$([ "$push" = 1 ] && echo 推送) $SERVICE 镜像 (TAG=${TAG:-latest}, PUSH=$push)" |
|||
TAG="${TAG:-latest}" REGISTRY="$REGISTRY" PUSH="$push" "$REPO_ROOT/build.sh" "$SERVICE" |
|||
} |
|||
|
|||
ensure_network_local() { |
|||
docker network inspect "$DOCKER_NETWORK" >/dev/null 2>&1 || docker network create "$DOCKER_NETWORK" |
|||
} |
|||
|
|||
# 本机 docker compose(gen_env 落为同目录 .env,既做变量替换又做容器 env_file) |
|||
compose_local() { |
|||
gen_env |
|||
ensure_network_local |
|||
( cd "$SVC_DIR" && docker compose --env-file .env "$@" ) |
|||
} |
|||
|
|||
# ── 远程 SSH 基础 ── |
|||
_ssh() { ssh -p "${DEPLOY_PORT:-22}" -i "${DEPLOY_KEY/#\~/$HOME}" -o StrictHostKeyChecking=accept-new "${DEPLOY_USER:-root}@${DEPLOY_HOST}" "$@"; } |
|||
_scp() { scp -P "${DEPLOY_PORT:-22}" -i "${DEPLOY_KEY/#\~/$HOME}" -o StrictHostKeyChecking=accept-new "$@"; } |
|||
_dest() { echo "${DEPLOY_USER:-root}@${DEPLOY_HOST}:$1"; } |
|||
|
|||
# 远程发布:同步配置 + 远程 login + pull + up |
|||
remote_deploy() { |
|||
: "${DEPLOY_HOST:?请在 deploy.sh 顶部 deploy_profile 的 $ENV_NAME 段填 DEPLOY_HOST}" |
|||
gen_env |
|||
|
|||
blue ">>> 同步 $SERVICE 配置到 ${DEPLOY_USER:-root}@${DEPLOY_HOST}:${DEPLOY_DIR}" |
|||
_ssh "mkdir -p '$DEPLOY_DIR'" |
|||
_scp "$SVC_DIR/docker-compose.yml" "$(_dest "$DEPLOY_DIR/docker-compose.yml")" |
|||
_scp "$SVC_DIR/.env" "$(_dest "$DEPLOY_DIR/.env")" |
|||
# 带 confs/ 的服务(console)一并同步配置并预建 log 目录 |
|||
if [ -d "$SVC_DIR/confs" ]; then |
|||
_ssh "mkdir -p '$DEPLOY_DIR/confs' '$DEPLOY_DIR/log'" |
|||
_scp -r "$SVC_DIR/confs/." "$(_dest "$DEPLOY_DIR/confs/")" |
|||
fi |
|||
|
|||
blue ">>> 远程拉起 $SERVICE" |
|||
[ -n "${REGISTRY_PASS:-}" ] && \ |
|||
_ssh "docker login '$REGISTRY' -u '${REGISTRY_USER:-admin}' -p '$REGISTRY_PASS'" |
|||
_ssh "docker network inspect '$DOCKER_NETWORK' >/dev/null 2>&1 || docker network create '$DOCKER_NETWORK'" |
|||
_ssh "cd '$DEPLOY_DIR' && docker compose --env-file .env pull && docker compose --env-file .env up -d --force-recreate" |
|||
} |
|||
|
|||
# 远程运维(down/restart/logs/ps/pull) |
|||
remote_compose() { |
|||
: "${DEPLOY_HOST:?请在 deploy.sh 顶部 deploy_profile 的 $ENV_NAME 段填 DEPLOY_HOST}" |
|||
_ssh "cd '$DEPLOY_DIR' && docker compose --env-file .env $*" |
|||
} |
|||
|
|||
# ── 分发 ── |
|||
deploy_profile # 写死的部署目标 / 仓库凭据 |
|||
load_env # env 文件里的运行时配置(TAG / 网络) |
|||
|
|||
if [ "$ENV_NAME" = local ]; then |
|||
case "$ACTION" in |
|||
up) compose_local up -d --force-recreate ;; |
|||
down) compose_local down ;; |
|||
restart) compose_local restart ;; |
|||
logs) compose_local logs -f --tail=120 ;; |
|||
ps) compose_local ps ;; |
|||
pull) compose_local pull ;; |
|||
build) build_push ;; |
|||
*) red "未知操作: ${ACTION}(local 支持 up|down|restart|logs|ps|pull|build)"; exit 1 ;; |
|||
esac |
|||
else |
|||
case "$ACTION" in |
|||
deploy) build_push; remote_deploy ;; |
|||
up) remote_deploy ;; |
|||
build) build_push ;; |
|||
pull) remote_compose pull ;; |
|||
down) remote_compose down ;; |
|||
restart) remote_compose restart ;; |
|||
ps) remote_compose ps ;; |
|||
logs) remote_compose logs -f --tail=120 ;; |
|||
*) red "未知操作: ${ACTION}(dev/prod 支持 deploy|up|build|pull|down|restart|logs|ps)"; exit 1 ;; |
|||
esac |
|||
fi |
|||
green "✓ $SERVICE $ENV_NAME $ACTION 完成" |
|||
Loading…
Reference in new issue