#!/bin/bash set -e # 遇到错误立即退出,确保部署流程的可靠性 # 颜色输出配置(增强可读性) RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # 重置颜色 COMPOSE_PROJECT_NAME="user_service" DOCKER_COMPOSE_FILE="./docker-compose.yaml" # 步骤1:停止指定名称的docker-compose编排 echo -e "${YELLOW}===== 第一步:停止编排名称为 $COMPOSE_PROJECT_NAME 的服务 ====="${NC} if [ -f "$DOCKER_COMPOSE_FILE" ]; then echo "正在停止服务..." docker-compose -f "$DOCKER_COMPOSE_FILE" -p "$COMPOSE_PROJECT_NAME" down if [ $? -eq 0 ]; then echo -e "${GREEN}编排 $COMPOSE_PROJECT_NAME 已成功停止${NC}" else echo -e "${RED}停止编排 $COMPOSE_PROJECT_NAME 失败!${NC}" exit 1 fi else echo -e "${RED}错误:未找到 $DOCKER_COMPOSE_FILE 文件${NC}" exit 1 fi # 步骤2:进入images目录加载所有镜像 echo -e "\n${YELLOW}===== 第二步:加载images目录下的所有镜像 ====="${NC} IMAGES_DIR="./images" if [ -d "$IMAGES_DIR" ]; then cd "$IMAGES_DIR" || { echo -e "${RED}错误:无法进入目录 $IMAGES_DIR${NC}" exit 1 } # 遍历所有镜像文件(支持.tar和.tar.gz格式) image_files=$(find . -type f -name "*.tar" -o -name "*.tar.gz") if [ -z "$image_files" ]; then echo -e "${YELLOW}警告:$IMAGES_DIR 目录下未找到镜像文件${NC}" else for file in $image_files; do echo "处理镜像文件:$file" # 临时加载镜像并获取输出(修复判断逻辑) temp_load_output=$(docker load -i "$file" 2>&1) # 检查临时加载是否成功(通过返回码判断,而非输出内容) if [ $? -ne 0 ]; then echo -e " ${RED}临时加载镜像 $file 失败:$temp_load_output${NC}" exit 1 fi # 从输出中提取镜像ID(兼容不同格式的输出) temp_image_id=$(echo "$temp_load_output" | awk '/Loaded image ID: / {print $4}') # 如果未提取到ID,尝试从"Loaded image: 镜像名:标签"中获取标签 if [ -z "$temp_image_id" ]; then image_tag=$(echo "$temp_load_output" | awk '/Loaded image: / {print $3}') if [ -n "$image_tag" ]; then temp_image_id=$(docker images --format '{{.ID}}' "$image_tag" | head -n 1) fi fi # 再次检查是否获取到镜像ID if [ -z "$temp_image_id" ]; then echo -e " ${RED}无法获取镜像 $file 的ID,加载失败${NC}" exit 1 fi # 获取镜像标签 image_tags=$(docker image inspect --format '{{range .RepoTags}}{{.}} {{end}}' "$temp_image_id") if [ -z "$image_tags" ]; then echo -e " ${YELLOW}警告:镜像 $file 没有标签信息,直接删除临时镜像${NC}" docker rmi -f "$temp_image_id" >/dev/null 2>&1 else # 先删除已存在的同名标签镜像 for tag in $image_tags; do if docker images --format '{{.Repository}}:{{.Tag}}' | grep -q "^$tag$"; then echo " 发现已存在镜像 $tag,正在删除..." if docker rmi -f "$tag" >/dev/null 2>&1; then echo -e " ${GREEN}成功删除镜像 $tag${NC}" else echo -e " ${RED}删除镜像 $tag 失败!${NC}" exit 1 fi fi done # 删除临时加载的镜像 docker rmi -f "$temp_image_id" >/dev/null 2>&1 fi # 正式加载镜像 echo " 正在加载镜像:$file" load_output=$(docker load -i "$file" 2>&1) if [ $? -eq 0 ]; then echo -e " ${GREEN}镜像 $file 加载成功:$load_output${NC}" else echo -e " ${RED}镜像 $file 加载失败:$load_output${NC}" exit 1 fi done fi # 返回根目录 cd .. || { echo -e "${RED}错误:无法返回根目录${NC}" exit 1 } else echo -e "${RED}错误:未找到 $IMAGES_DIR 目录${NC}" exit 1 fi # 步骤3:启动指定名称的docker-compose编排 echo -e "\n${YELLOW}===== 第三步:启动编排名称为 $COMPOSE_PROJECT_NAME 的服务 ====="${NC} if [ -f "$DOCKER_COMPOSE_FILE" ]; then echo "正在启动服务..." docker-compose -f "$DOCKER_COMPOSE_FILE" -p "$COMPOSE_PROJECT_NAME" up -d if [ $? -eq 0 ]; then echo -e "${GREEN}编排 $COMPOSE_PROJECT_NAME 启动成功!${NC}" else echo -e "${RED}启动编排 $COMPOSE_PROJECT_NAME 失败!${NC}" exit 1 fi else echo -e "${RED}错误:未找到 $DOCKER_COMPOSE_FILE 文件${NC}" exit 1 fi echo -e "\n${GREEN}===== 所有部署步骤已完成 ====="${NC}