#!/usr/bin/env bash # ═══════════════════════════════════════════════════════════════════ # hotfix.sh — 紧急单文件修复(仅限紧急情况) # # 用法: # bash deploy/hotfix.sh <服务名> <宿主文件> <容器内路径> # bash deploy/hotfix.sh backend /tmp/fix.py /app/app/services/fix.py # # ⚠️ 强制收口: # docker cp 只是把文件放进运行中的容器,不进镜像——容器一重建即丢。 # 用后必须立即: ① git 提交改动 ② 走 deploy.sh 正式部署,否则手工改动与仓库不一致(8-09 教训)。 # ═══════════════════════════════════════════════════════════════════ set -euo pipefail DEPLOY_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="$(cd "$DEPLOY_DIR/.." && pwd)" cd "$REPO_ROOT" COMPOSE_FILE="docker-compose.prod.yml" GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; NC='\033[0m' info() { echo -e "${GREEN}[✓]${NC} $1"; } warn() { echo -e "${YELLOW}[!]${NC} $1"; } error() { echo -e "${RED}[✗]${NC} $1"; exit 1; } if [ "$#" -ne 3 ]; then echo "用法: bash deploy/hotfix.sh <服务名> <宿主文件> <容器内路径>" exit 1 fi SERVICE="$1"; HOST_FILE="$2"; CONTAINER_PATH="$3" [ -f "$HOST_FILE" ] || error "宿主文件不存在: $HOST_FILE" info "复制 $HOST_FILE → $SERVICE:$CONTAINER_PATH" docker compose -f "$COMPOSE_FILE" cp "$HOST_FILE" "$SERVICE:$CONTAINER_PATH" if [ "$SERVICE" = "backend" ] || [ "$SERVICE" = "worker" ]; then info "backend/worker 需重启才生效: docker compose -f $COMPOSE_FILE restart $SERVICE" fi echo "" echo -e "${RED}════════════════════════════════════════════════════════════════${NC}" echo -e "${RED}⚠️ hotfix 是脆弱窗口:docker cp 不进镜像,容器重建即丢!${NC}" echo -e "${RED} 必须立即完成以下收口,否则改动丢失且与仓库不一致:${NC}" echo -e "${RED} 1. 把改动同步回仓库(git 提交 + push)${NC}" echo -e "${RED} 2. 尽快走正式部署: bash deploy/deploy.sh${NC}" echo -e "${RED}════════════════════════════════════════════════════════════════${NC}"