XuqmGroup-PrivateDeploy/scripts/renew-cert.sh
徐勤民 9eabe0d699 feat: implement complete private deployment scripts (P1-P4)
- upgrade.sh/rollback.sh: backup→pull→rolling restart→healthcheck→auto-rollback
- backup.sh/restore.sh: mysqldump+redis BGSAVE+config tar, SHA256 manifest, restore with checksum verification
- healthcheck.sh: Docker/container/MySQL/Redis/HTTP/disk checks, JSON output to .deploy-state/
- doctor.sh: sanitized diagnostics archive, vendor API TCP connectivity, cert expiry
- export-offline-bundle.sh: docker pull+save for all profile images, load-images.sh, SHA256
- configure.sh: interactive/non-interactive mode, MySQL/Redis mode selection, domain prompts
- enable-service.sh: domain validation, docker pull + compose up, healthcheck
- disable-service.sh: compose stop+rm, profile removal, render-config
- renew-cert.sh: acme.sh/certbot, --dry-run, backup old cert, nginx reload on success
- alert-webhook.sh: WeCom/DingTalk/Feishu webhook, message sanitization
- bench.sh: ab/wrk/curl benchmark, JSON report with docker stats
- rotate-secrets.sh: JWT and internal token rotation
- vendor credential templates: push.env and store-submit.env with full credential comments
- render-config.sh: auto-sync SDK URL env vars (SDK_FILE_SERVICE_URL, SDK_IM_API_URL, SDK_IM_WS_URL)
- All scripts pass bash -n syntax check

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 20:49:25 +08:00

72 行
2.7 KiB
Bash
可执行文件

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
. "$ROOT_DIR/scripts/lib.sh"
load_env
DRY_RUN=false
[ "${1:-}" = "--dry-run" ] && DRY_RUN=true
CERT_DIR="${CERT_DIR:-$ROOT_DIR/config/nginx/certs}"
DOMAIN="${CONSOLE_DOMAIN:-}"
DOMAIN="${DOMAIN#https://}"
DOMAIN="${DOMAIN%%/*}"
audit "renew-cert" "STARTED" "domain=$DOMAIN dry_run=$DRY_RUN"
progress "renew-cert" "STARTED" "domain=$DOMAIN"
[ -n "$DOMAIN" ] || fail_json "XUQM_PRIVATE_5010" "CONSOLE_DOMAIN not set" "renew-cert"
mkdir -p "$CERT_DIR"
# Backup existing certs
CERT_FILE="$CERT_DIR/${DOMAIN}.crt"
KEY_FILE="$CERT_DIR/${DOMAIN}.key"
if [ -f "$CERT_FILE" ]; then
CERT_BACKUP="${CERT_FILE}.$(date +%Y%m%d%H%M%S).bak"
cp "$CERT_FILE" "$CERT_BACKUP"
cp "$KEY_FILE" "${KEY_FILE}.$(date +%Y%m%d%H%M%S).bak"
audit "renew-cert" "BACKUP_DONE" "backed up to $CERT_BACKUP"
fi
if [ "$DRY_RUN" = "true" ]; then
printf '[DRY-RUN] Would renew certificate for %s\n' "$DOMAIN"
printf '[DRY-RUN] Would reload nginx after renewal\n'
audit "renew-cert" "DRY_RUN" "domain=$DOMAIN"
exit 0
fi
# Try acme.sh first, then certbot
if command -v acme.sh >/dev/null 2>&1; then
acme.sh --renew -d "$DOMAIN" --force 2>&1 | tee -a "$ROOT_DIR/logs/cert-renew.log" || {
audit "renew-cert" "FAILED" "acme.sh renewal failed for $DOMAIN"
"$ROOT_DIR/scripts/alert-webhook.sh" "CERT_RENEW_FAILED" "Certificate renewal failed for $DOMAIN" 2>/dev/null || true
fail_json "XUQM_PRIVATE_5011" "certificate renewal failed for $DOMAIN" "renew-cert"
}
# Copy renewed cert to nginx config dir
acme.sh --install-cert -d "$DOMAIN" \
--cert-file "$CERT_FILE" \
--key-file "$KEY_FILE" \
--reloadcmd "docker exec $(compose ps -q nginx | head -1) nginx -s reload" 2>/dev/null || true
elif command -v certbot >/dev/null 2>&1; then
certbot renew --cert-name "$DOMAIN" --non-interactive 2>&1 | tee -a "$ROOT_DIR/logs/cert-renew.log" || {
audit "renew-cert" "FAILED" "certbot renewal failed for $DOMAIN"
"$ROOT_DIR/scripts/alert-webhook.sh" "CERT_RENEW_FAILED" "Certificate renewal failed for $DOMAIN" 2>/dev/null || true
fail_json "XUQM_PRIVATE_5011" "certificate renewal failed for $DOMAIN" "renew-cert"
}
# Reload nginx
NGINX_CTR="$(compose ps -q nginx 2>/dev/null | head -1 || true)"
[ -n "$NGINX_CTR" ] && docker exec "$NGINX_CTR" nginx -s reload
else
fail_json "XUQM_PRIVATE_5012" "neither acme.sh nor certbot found" "renew-cert"
fi
audit "renew-cert" "DONE" "domain=$DOMAIN"
progress "renew-cert" "DONE" "domain=$DOMAIN"
printf 'Certificate renewed for %s\n' "$DOMAIN"
# Crontab setup hint (output to stdout)
printf '\n# Add to crontab for automatic renewal:\n'
printf '# 0 3 * * * %s/scripts/renew-cert.sh >> %s/logs/cert-renew.log 2>&1\n' "$ROOT_DIR" "$ROOT_DIR"