131 lines
5.1 KiB
Bash
131 lines
5.1 KiB
Bash
#!/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} |