环境配置统一以 .env 为单一事实来源,移除 .ctms-env
- 删除 .ctms-env:环境名由 .env 的 COMPOSE_PROJECT_NAME 反推 (ctms_detect_env),健康检查地址改存 .env 的 CTMS_BASE_URL - prepare_env_file 由“已存在则整体跳过”改为逐项探测补全: 身份类缺失补目标值、密钥类缺失/空才生成、已有值一律不动 - resolve_effective_config 放宽为“冲突才致命”:身份类缺失交给 补全,仅 COMPOSE_PROJECT_NAME/ENV 与目标环境冲突时报错停止 (防止覆盖后孤立旧环境容器) - 新增 ctms_env_has_key 区分“键缺失”与“键存在但空值” (dev 的 LOGIN_RSA_PRIVATE_KEY= 是合法空值) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+67
-24
@@ -149,20 +149,18 @@ resolve_effective_config() {
|
||||
env_runtime_env="$(read_env_value ENV || true)"
|
||||
env_login_key_id="$(read_env_value LOGIN_RSA_KEY_ID || true)"
|
||||
|
||||
[[ -n "$env_project_name" ]] || fail ".env 缺少 COMPOSE_PROJECT_NAME,请补齐后重试"
|
||||
[[ -n "$env_runtime_env" ]] || fail ".env 缺少 ENV,请补齐后重试"
|
||||
[[ -n "$env_login_key_id" ]] || fail ".env 缺少 LOGIN_RSA_KEY_ID,请补齐后重试"
|
||||
|
||||
if [[ "$env_project_name" != "$desired_project_name" ]]; then
|
||||
fail ".env 的 COMPOSE_PROJECT_NAME=$env_project_name 与目标环境 $TARGET_ENV 期望值 $desired_project_name 不一致"
|
||||
# 身份类“冲突”才致命(防止覆盖后孤立原环境的容器);“缺失”留给 prepare_env_file 补全。
|
||||
if [[ -n "$env_project_name" && "$env_project_name" != "$desired_project_name" ]]; then
|
||||
fail ".env 的 COMPOSE_PROJECT_NAME=$env_project_name 与目标环境 $TARGET_ENV 期望值 $desired_project_name 不一致;如需切换环境请先卸载旧环境或手动清理 .env"
|
||||
fi
|
||||
if [[ "$env_runtime_env" != "$desired_runtime_env" ]]; then
|
||||
fail ".env 的 ENV=$env_runtime_env 与目标环境 $TARGET_ENV 期望值 $desired_runtime_env 不一致"
|
||||
if [[ -n "$env_runtime_env" && "$env_runtime_env" != "$desired_runtime_env" ]]; then
|
||||
fail ".env 的 ENV=$env_runtime_env 与目标环境 $TARGET_ENV 期望值 $desired_runtime_env 不一致;如需切换环境请先卸载旧环境或手动清理 .env"
|
||||
fi
|
||||
|
||||
EFFECTIVE_PROJECT_NAME="$env_project_name"
|
||||
EFFECTIVE_RUNTIME_ENV="$env_runtime_env"
|
||||
EFFECTIVE_LOGIN_KEY_ID="$env_login_key_id"
|
||||
# 仅采用 .env 中实际存在的值,缺失项保留目标默认(由 prepare_env_file 写回)。
|
||||
[[ -n "$env_project_name" ]] && EFFECTIVE_PROJECT_NAME="$env_project_name"
|
||||
[[ -n "$env_runtime_env" ]] && EFFECTIVE_RUNTIME_ENV="$env_runtime_env"
|
||||
[[ -n "$env_login_key_id" ]] && EFFECTIVE_LOGIN_KEY_ID="$env_login_key_id"
|
||||
}
|
||||
|
||||
# 生成单行转义 PEM:行间用 \n 连接,末尾不追加多余 \n
|
||||
@@ -255,25 +253,68 @@ prepare_env_file() {
|
||||
local project_name="$1" runtime_env="$2" login_key_id="$3"
|
||||
local jwt_secret="" rsa_private_key=""
|
||||
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
ok "检测到现有 .env,保留原文件并跳过写入"
|
||||
# 首次安装:无 .env,写全量。
|
||||
if [[ ! -f "$ENV_FILE" ]]; then
|
||||
if [[ "$TARGET_ENV" == "dev" ]]; then
|
||||
jwt_secret="dev-secret"
|
||||
rsa_private_key=""
|
||||
else
|
||||
jwt_secret="$(generate_jwt_secret)"
|
||||
ok "已生成新的 JWT_SECRET_KEY"
|
||||
log "正在生成 RSA 2048 密钥对,请稍候…"
|
||||
rsa_private_key="$(generate_escaped_private_key)"
|
||||
ok "已生成新的 LOGIN_RSA_PRIVATE_KEY"
|
||||
fi
|
||||
ctms_write_env_file "$project_name" "$runtime_env" "$login_key_id" "$jwt_secret" "$rsa_private_key"
|
||||
ok ".env 写入完成"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "$TARGET_ENV" == "dev" ]]; then
|
||||
jwt_secret="dev-secret"
|
||||
rsa_private_key=""
|
||||
else
|
||||
jwt_secret="$(generate_jwt_secret)"
|
||||
ok "已生成新的 JWT_SECRET_KEY"
|
||||
# 已有 .env:逐项探测,缺则补全,已有值一律不动(身份类冲突已在 resolve_effective_config 拦截)。
|
||||
local repaired=0
|
||||
|
||||
log "正在生成 RSA 2048 密钥对,请稍候…"
|
||||
rsa_private_key="$(generate_escaped_private_key)"
|
||||
ok "已生成新的 LOGIN_RSA_PRIVATE_KEY"
|
||||
# 身份类:缺失补目标值
|
||||
if ! ctms_env_has_key COMPOSE_PROJECT_NAME; then
|
||||
ctms_upsert_env_value COMPOSE_PROJECT_NAME "$project_name"; repaired=1
|
||||
warn ".env 缺少 COMPOSE_PROJECT_NAME,已补为 $project_name"
|
||||
fi
|
||||
if ! ctms_env_has_key ENV; then
|
||||
ctms_upsert_env_value ENV "$runtime_env"; repaired=1
|
||||
warn ".env 缺少 ENV,已补为 $runtime_env"
|
||||
fi
|
||||
if ! ctms_env_has_key LOGIN_RSA_KEY_ID; then
|
||||
ctms_upsert_env_value LOGIN_RSA_KEY_ID "$login_key_id"; repaired=1
|
||||
warn ".env 缺少 LOGIN_RSA_KEY_ID,已补为 $login_key_id"
|
||||
fi
|
||||
|
||||
ctms_write_env_file "$project_name" "$runtime_env" "$login_key_id" "$jwt_secret" "$rsa_private_key"
|
||||
ok ".env 写入完成"
|
||||
# JWT 密钥:缺失或空才补(保留已有值,避免使现有会话失效)
|
||||
if [[ -z "$(read_env_value JWT_SECRET_KEY || true)" ]]; then
|
||||
if [[ "$TARGET_ENV" == "dev" ]]; then
|
||||
jwt_secret="dev-secret"
|
||||
else
|
||||
jwt_secret="$(generate_jwt_secret)"
|
||||
fi
|
||||
ctms_upsert_env_value JWT_SECRET_KEY "$jwt_secret"; repaired=1
|
||||
warn ".env 缺少 JWT_SECRET_KEY,已补全"
|
||||
fi
|
||||
|
||||
# RSA 私钥:非 dev 缺失或空才生成;dev 仅确保键存在(允许空值)
|
||||
if [[ -z "$(read_env_value LOGIN_RSA_PRIVATE_KEY || true)" ]]; then
|
||||
if [[ "$TARGET_ENV" != "dev" ]]; then
|
||||
log "正在生成 RSA 2048 密钥对,请稍候…"
|
||||
rsa_private_key="$(generate_escaped_private_key)"
|
||||
ctms_upsert_env_value LOGIN_RSA_PRIVATE_KEY "$rsa_private_key"; repaired=1
|
||||
warn ".env 缺少 LOGIN_RSA_PRIVATE_KEY,已生成新密钥"
|
||||
elif ! ctms_env_has_key LOGIN_RSA_PRIVATE_KEY; then
|
||||
ctms_upsert_env_value LOGIN_RSA_PRIVATE_KEY ""; repaired=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$repaired" -eq 1 ]]; then
|
||||
ok ".env 已补全缺失项"
|
||||
else
|
||||
ok "检测到完整 .env,沿用现有配置"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Docker 流程 ───────────────────────────────
|
||||
@@ -456,6 +497,8 @@ main() {
|
||||
confirm_install "$EFFECTIVE_PROJECT_NAME" "$EFFECTIVE_RUNTIME_ENV"
|
||||
prepare_env_file "$project_name" "$runtime_env" "$login_key_id"
|
||||
sync_frontend_build_env "$runtime_env"
|
||||
# 健康检查地址持久化到 .env(单一事实来源);独立 upsert,绕开 prepare_env_file 对已存在 .env 的跳过。
|
||||
ctms_upsert_env_value CTMS_BASE_URL "$BASE_URL"
|
||||
run_compose_config
|
||||
run_backend_init
|
||||
run_build_and_start
|
||||
|
||||
Reference in New Issue
Block a user