feat(deploy): 默认安装 ONLYOFFICE 标准组件

This commit is contained in:
Cheng Zhou
2026-07-16 17:09:12 +08:00
parent 3e77127687
commit 1837ceff58
8 changed files with 128 additions and 52 deletions
+59 -6
View File
@@ -173,6 +173,10 @@ generate_jwt_secret() {
openssl rand -hex 32
}
generate_onlyoffice_instance_id() {
printf 'ctms-%s-%s' "$TARGET_ENV" "$(openssl rand -hex 8)"
}
# ── 地址解析 ─────────────────────────────────
resolve_base_url() {
[[ -z "$BASE_URL" ]] && BASE_URL="$(default_base_url)"
@@ -221,6 +225,7 @@ confirm_install() {
row "健康检查地址" "$BASE_URL" "${CC_INFO}"
row ".env 文件" "$env_status"
row "pg_data 目录" "$pg_status"
row "ONLYOFFICE" "标准组件(自动安装)" "${CC_INFO}"
row "镜像构建" "$build_status"
row "数据库迁移" "$migrate_status"
ctms_box_bottom "${CC_PRIMARY}${C_BOLD}" "$w"
@@ -252,6 +257,7 @@ prepare_env_file() {
step "准备环境配置文件"
local project_name="$1" runtime_env="$2" login_key_id="$3"
local jwt_secret="" rsa_private_key=""
local onlyoffice_jwt_secret="" onlyoffice_instance_id=""
# 首次安装:无 .env,写全量。
if [[ ! -f "$ENV_FILE" ]]; then
@@ -265,7 +271,12 @@ prepare_env_file() {
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"
onlyoffice_jwt_secret="$(generate_jwt_secret)"
onlyoffice_instance_id="$(generate_onlyoffice_instance_id)"
ok "已生成独立的 ONLYOFFICE JWT 密钥与实例标识"
ctms_write_env_file \
"$project_name" "$runtime_env" "$login_key_id" "$jwt_secret" "$rsa_private_key" \
"$onlyoffice_jwt_secret" "$onlyoffice_instance_id"
ok ".env 写入完成"
return
fi
@@ -310,6 +321,36 @@ prepare_env_file() {
fi
fi
# ONLYOFFICE 是标准组件:旧环境升级时自动启用并补齐独立安全配置。
if [[ "$(read_env_value ONLYOFFICE_ENABLED || true)" != "true" ]]; then
ctms_upsert_env_value ONLYOFFICE_ENABLED true; repaired=1
warn ".env 中 ONLYOFFICE 未启用,已作为标准组件启用"
fi
onlyoffice_jwt_secret="$(read_env_value ONLYOFFICE_JWT_SECRET || true)"
jwt_secret="$(read_env_value JWT_SECRET_KEY || true)"
if [[ ${#onlyoffice_jwt_secret} -lt 32 || "$onlyoffice_jwt_secret" == "$jwt_secret" ]]; then
onlyoffice_jwt_secret="$(generate_jwt_secret)"
ctms_upsert_env_value ONLYOFFICE_JWT_SECRET "$onlyoffice_jwt_secret"; repaired=1
warn ".env 缺少有效的独立 ONLYOFFICE_JWT_SECRET,已生成并补全"
fi
if [[ -z "$(read_env_value ONLYOFFICE_INSTANCE_ID || true)" ]]; then
onlyoffice_instance_id="$(generate_onlyoffice_instance_id)"
ctms_upsert_env_value ONLYOFFICE_INSTANCE_ID "$onlyoffice_instance_id"; repaired=1
warn ".env 缺少 ONLYOFFICE_INSTANCE_ID,已生成稳定实例标识"
fi
if [[ -z "$(read_env_value ONLYOFFICE_INTERNAL_URL || true)" ]]; then
ctms_upsert_env_value ONLYOFFICE_INTERNAL_URL http://onlyoffice; repaired=1
fi
if [[ -z "$(read_env_value ONLYOFFICE_STORAGE_BASE_URL || true)" ]]; then
ctms_upsert_env_value ONLYOFFICE_STORAGE_BASE_URL http://backend:8000; repaired=1
fi
if [[ -z "$(read_env_value ONLYOFFICE_CONFIG_TTL_SECONDS || true)" ]]; then
ctms_upsert_env_value ONLYOFFICE_CONFIG_TTL_SECONDS 300; repaired=1
fi
if [[ "$repaired" -eq 1 ]]; then
ok ".env 已补全缺失项"
else
@@ -320,7 +361,8 @@ prepare_env_file() {
# ── Docker 流程 ───────────────────────────────
run_compose_config() {
step "校验 Docker Compose 配置"
ctms_run_quiet "Docker Compose 配置语法校验" -- compose_cmd config
# config 会展开并输出 JWT/RSA 等敏感环境变量;即使启用 --verbose 也只做静默校验。
ctms_run_quiet "Docker Compose 配置语法校验" -- compose_cmd config --quiet
}
run_backend_init() {
@@ -338,14 +380,14 @@ run_build_and_start() {
if [[ "$SKIP_BUILD" -eq 1 ]]; then
step "启动服务(跳过镜像构建)"
if [[ "$TARGET_ENV" == "dev" ]]; then
ctms_run_quiet "启动开发容器并刷新后端/Nginx/Vite" -- compose_cmd up -d --force-recreate backend nginx frontend-dev
ctms_run_quiet "启动开发容器并刷新后端/ONLYOFFICE/Nginx/Vite" -- compose_cmd up -d --force-recreate backend onlyoffice nginx frontend-dev
else
ctms_run_quiet "启动容器" -- compose_cmd up -d
fi
else
step "构建镜像并启动服务"
if [[ "$TARGET_ENV" == "dev" ]]; then
CTMS_LIVE_OUTPUT=1 ctms_run_quiet "构建并刷新开发容器(首次较慢)" -- compose_cmd up -d --build --force-recreate backend nginx frontend-dev
CTMS_LIVE_OUTPUT=1 ctms_run_quiet "构建并刷新开发容器(首次较慢)" -- compose_cmd up -d --build --force-recreate backend onlyoffice nginx frontend-dev
else
CTMS_LIVE_OUTPUT=1 ctms_run_quiet "构建镜像并启动容器(首次较慢)" -- compose_cmd up -d --build
fi
@@ -366,7 +408,7 @@ check_container_status() {
step "检查容器运行状态"
local running
running="$(compose_cmd ps --services --filter status=running 2>/dev/null || true)"
local services=(db backend nginx)
local services=(db backend onlyoffice nginx)
[[ "$TARGET_ENV" != "dev" ]] || services+=(frontend-dev)
local svc
for svc in "${services[@]}"; do
@@ -398,6 +440,14 @@ if settings.LOGIN_RSA_KEY_ID != expected_key_id:
sys.exit("LOGIN_RSA_KEY_ID 不匹配")
if expected_env == "production" and settings.JWT_SECRET_KEY == "dev-secret":
sys.exit("生产环境不允许使用默认 JWT_SECRET_KEY")
if not settings.ONLYOFFICE_ENABLED:
sys.exit("ONLYOFFICE 必须作为标准组件启用")
if len(settings.ONLYOFFICE_JWT_SECRET or "") < 32:
sys.exit("ONLYOFFICE_JWT_SECRET 未正确配置")
if settings.ONLYOFFICE_JWT_SECRET == settings.JWT_SECRET_KEY:
sys.exit("ONLYOFFICE_JWT_SECRET 不得复用登录 JWT 密钥")
if not settings.ONLYOFFICE_INSTANCE_ID:
sys.exit("ONLYOFFICE_INSTANCE_ID 未配置")
if expect_rsa:
if not settings.LOGIN_RSA_PRIVATE_KEY:
sys.exit("LOGIN_RSA_PRIVATE_KEY 未配置")
@@ -463,6 +513,7 @@ run_health_checks() {
check_http_endpoint "/health"
check_http_endpoint "/readyz"
check_http_endpoint "/api/v1/auth/login-key"
check_http_endpoint "/onlyoffice/healthcheck" 120
if [[ "$TARGET_ENV" == "dev" ]]; then
check_http_endpoint "/" 60
fi
@@ -515,4 +566,6 @@ main() {
show_success
}
main "$@"
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
main "$@"
fi