#!/usr/bin/env bash set -Eeuo pipefail # 现场临时热替换 syslog-consumer-rule 容器内的 JAR。 # 默认容器名和容器内路径来自当前生产镜像: # syslog-consumer-rule-dm:/app/syslog-consumer-rule.jar # # 用法: # ./upgrade-doc/replace-syslog-consumer-rule-jar.sh # ./upgrade-doc/replace-syslog-consumer-rule-jar.sh /path/to/syslog-consumer-rule-1.0.0.jar CONTAINER_NAME="syslog-consumer-rule-dm" CONTAINER_JAR="/app/syslog-consumer-rule.jar" SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) PROJECT_DIR=$(cd "${SCRIPT_DIR}/.." && pwd) DEFAULT_JAR="${PROJECT_DIR}/syslog-consumer-rule/target/syslog-consumer-rule-1.0.0.jar" LOCAL_JAR="${1:-${DEFAULT_JAR}}" BACKUP_DIR="${SCRIPT_DIR}/backups" BACKUP_JAR="${BACKUP_DIR}/syslog-consumer-rule-$(date '+%Y%m%d-%H%M%S').jar" STARTED_AT="" fail() { echo "ERROR: $*" >&2 exit 1 } command -v docker >/dev/null 2>&1 || fail "未找到 docker 命令" [[ -f "${LOCAL_JAR}" && -s "${LOCAL_JAR}" ]] || fail "新 JAR 不存在或为空: ${LOCAL_JAR}" docker inspect "${CONTAINER_NAME}" >/dev/null 2>&1 || fail "容器不存在: ${CONTAINER_NAME}" mkdir -p "${BACKUP_DIR}" echo "[1/5] 备份容器内旧 JAR" docker cp "${CONTAINER_NAME}:${CONTAINER_JAR}" "${BACKUP_JAR}" echo "旧 JAR 已备份到: ${BACKUP_JAR}" echo "[2/5] 停止容器 ${CONTAINER_NAME}" docker stop "${CONTAINER_NAME}" >/dev/null restart_after_failure() { local exit_code=$? if [[ ${exit_code} -ne 0 ]]; then echo "替换过程失败,尝试重新启动容器。旧 JAR 备份位于: ${BACKUP_JAR}" >&2 docker start "${CONTAINER_NAME}" >/dev/null 2>&1 || true fi exit "${exit_code}" } trap restart_after_failure ERR echo "[3/5] 替换容器内 JAR" docker cp "${LOCAL_JAR}" "${CONTAINER_NAME}:${CONTAINER_JAR}" echo "[4/5] 启动容器" STARTED_AT=$(date -u '+%Y-%m-%dT%H:%M:%SZ') docker start "${CONTAINER_NAME}" >/dev/null sleep 8 RUNNING=$(docker inspect --format '{{.State.Running}}' "${CONTAINER_NAME}") if [[ "${RUNNING}" != "true" ]]; then trap - ERR echo "ERROR: 容器启动后未保持运行,启动日志如下:" >&2 docker logs --since "${STARTED_AT}" "${CONTAINER_NAME}" 2>&1 | tail -80 >&2 || true echo "可使用以下命令回滚:" >&2 echo "docker cp '${BACKUP_JAR}' '${CONTAINER_NAME}:${CONTAINER_JAR}' && docker start '${CONTAINER_NAME}'" >&2 exit 1 fi trap - ERR echo "[5/5] 替换完成,显示本次启动日志" echo "新 JAR: ${LOCAL_JAR}" echo "旧 JAR 备份: ${BACKUP_JAR}" echo "注意:以后若删除或重新创建容器,容器内替换会丢失,仍需更新镜像。" docker logs --since "${STARTED_AT}" "${CONTAINER_NAME}" 2>&1 | tail -80