#!/bin/bash # deploy-swarm.sh set -e # 仓库用户名 USER_NAME="bmy" # 仓库密码 USER_PASSWORD="lb714500." # 仓库地址 REGISTRY="registry.bmycode.help" # 镜像名称 IMAGE_NAME="${REGISTRY}/app-product" # tag 标签 TAG="v$(date +%Y%m%d-%H%M%S)" # 完整路径 FULL_IMAGE="${IMAGE_NAME}:${TAG}" # 工作服务器列表(多个服务器) WORKER_HOSTS=("192.168.139.120" "192.168.139.242") WORKER_USER="root" WORKER_PASSWORD="lb714500." echo "=== 1 登录私有镜像仓库 ===" if ! echo "${USER_PASSWORD}" | docker login ${REGISTRY} -u ${USER_NAME} --password-stdin; then echo "错误: 无法登录到私有仓库 ${REGISTRY}" exit 1 fi echo "=== 2 构建 app-product 镜像 ===" docker build \ -f docker/Dockerfile \ -t ${FULL_IMAGE} \ -t ${IMAGE_NAME}:latest \ . echo "=== 3 推送镜像到私有仓库 ===" docker push ${FULL_IMAGE} docker push ${IMAGE_NAME}:latest echo "=== 4 在工作服务器上拉取最新镜像 ===" for WORKER_HOST in "${WORKER_HOSTS[@]}"; do echo "" echo "正在连接到工作服务器: ${WORKER_HOST}" if sshpass -p "${WORKER_PASSWORD}" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${WORKER_USER}@${WORKER_HOST} " echo '在工作服务器 ${WORKER_HOST} 上登录私有仓库...' if echo '${USER_PASSWORD}' | docker login ${REGISTRY} -u ${USER_NAME} --password-stdin; then echo '拉取最新镜像...' docker pull ${FULL_IMAGE} docker pull ${IMAGE_NAME}:latest echo '镜像拉取完成' echo '清理旧的 app-product 镜像...' # 删除除了本次 FULL_IMAGE 和 latest 之外的所有 app-product 镜像 docker images ${IMAGE_NAME} --format 'table {{.Repository}}:{{.Tag}}' | \ grep -v '${FULL_IMAGE}' | \ grep -v '${IMAGE_NAME}:latest' | \ grep '${IMAGE_NAME}' | \ xargs -r docker rmi -f || true else echo '错误: 无法在工作服务器上登录私有仓库' exit 1 fi "; then echo "✓ 服务器 ${WORKER_HOST} 镜像拉取成功" else echo "✗ 服务器 ${WORKER_HOST} 镜像拉取失败" exit 1 fi done echo "=== 5 更新 docker-compose 文件中的镜像标签 ===" sed "s|image: app-product:latest|image: ${FULL_IMAGE}|g" docker/app-product.yml > docker/app-product-deploy.yml echo "=== 6 部署到 Swarm 集群 ===" docker stack deploy -c docker/app-product-deploy.yml app-product echo "=== 7 恢复原始配置文件 ===" rm -f docker/app-product-deploy.yml echo "=== 8 清理本地多余镜像 ===" # 清理本地:删除除了本次 FULL_IMAGE 和 latest 之外的所有 app-product 镜像 echo "清理本地旧的 app-product 镜像..." docker images ${IMAGE_NAME} --format 'table {{.Repository}}:{{.Tag}}' | \ grep -v "${FULL_IMAGE}" | \ grep -v "${IMAGE_NAME}:latest" | \ grep "${IMAGE_NAME}" | \ xargs -r docker rmi -f || true # 清理悬空镜像 docker image prune -f echo "=== 9 验证部署状态 ===" docker stack ps app-product echo "=== 部署完成 ==="