Git+Docker自动化部署脚本
从Git拉取代码,构建Docker镜像,停止旧容器,启动新容器,实现一键自动化部署
详细内容
#!/bin/bash
# ==========================================
# Git+Docker自动化部署脚本
# 用途:从Git拉取代码,构建Docker镜像,部署容器
# 使用方法:bash auto_deploy.sh
# ==========================================
# 配置
APP_NAME="${APP_NAME:-myapp}"
GIT_REPO="${GIT_REPO:-https://github.com/user/repo.git}"
GIT_BRANCH="${GIT_BRANCH:-main}"
DEPLOY_DIR="${DEPLOY_DIR:-/opt/deploy/$APP_NAME}"
DOCKERFILE_PATH="${DOCKERFILE_PATH:-.}"
IMAGE_NAME="${IMAGE_NAME:-$APP_NAME}"
CONTAINER_NAME="${CONTAINER_NAME:-$APP_NAME}"
HOST_PORT="${HOST_PORT:-8080}"
CONTAINER_PORT="${CONTAINER_PORT:-80}"
ENV_FILE="${ENV_FILE:-}"
VOLUME_MOUNTS="${VOLUME_MOUNTS:-}"
KEEP_IMAGES="${KEEP_IMAGES:-3}"
echo "========== 自动化部署开始 =========="
echo "部署时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "应用名称: $APP_NAME"
echo "Git仓库: $GIT_REPO"
echo "分支: $GIT_BRANCH"
echo ""
# 检查依赖
check_dependency() {
if ! command -v $1 &> /dev/null; then
echo "❌ 错误: $1 未安装"
exit 1
fi
}
check_dependency git
check_dependency docker
# 检查Docker服务
if ! docker info &> /dev/null; then
echo "❌ 错误: Docker服务未运行"
exit 1
fi
echo "✅ 依赖检查通过"
echo ""
# 创建部署目录
mkdir -p "$DEPLOY_DIR"
cd "$DEPLOY_DIR" || exit 1
# 1. 拉取代码
echo "【1. 拉取代码】"
if [ -d ".git" ]; then
echo " 已有仓库,执行git pull..."
git fetch origin
git checkout "$GIT_BRANCH"
git pull origin "$GIT_BRANCH"
else
echo " 克隆仓库..."
git clone -b "$GIT_BRANCH" "$GIT_REPO" .
fi
if [ $? -ne 0 ]; then
echo "❌ 代码拉取失败"
exit 1
fi
COMMIT_ID=$(git rev-parse --short HEAD)
COMMIT_MSG=$(git log -1 --pretty=%B)
echo " ✅ 代码拉取成功"
echo " Commit: $COMMIT_ID"
echo " 说明: $COMMIT_MSG"
echo ""
# 2. 构建Docker镜像
echo "【2. 构建Docker镜像】"
IMAGE_TAG="${IMAGE_NAME}:${COMMIT_ID}"
IMAGE_LATEST="${IMAGE_NAME}:latest"
echo " 构建镜像: $IMAGE_TAG"
cd "$DOCKERFILE_PATH" || exit 1
docker build -t "$IMAGE_TAG" -t "$IMAGE_LATEST" .
if [ $? -ne 0 ]; then
echo "❌ 镜像构建失败"
exit 1
fi
echo " ✅ 镜像构建成功"
docker images | grep "$IMAGE_NAME" | head -5
echo ""
# 3. 停止并删除旧容器
echo "【3. 停止旧容器】"
if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
echo " 停止容器: $CONTAINER_NAME"
docker stop "$CONTAINER_NAME"
echo " 删除容器: $CONTAINER_NAME"
docker rm "$CONTAINER_NAME"
echo " ✅ 旧容器已清理"
else
echo " 无旧容器,跳过"
fi
echo ""
# 4. 启动新容器
echo "【4. 启动新容器】"
DOCKER_RUN_CMD="docker run -d --name $CONTAINER_NAME -p ${HOST_PORT}:${CONTAINER_PORT} --restart=always"
# 添加环境变量文件
if [ -n "$ENV_FILE" ] && [ -f "$ENV_FILE" ]; then
DOCKER_RUN_CMD="$DOCKER_RUN_CMD --env-file $ENV_FILE"
fi
# 添加卷挂载
if [ -n "$VOLUME_MOUNTS" ]; then
for mount in $VOLUME_MOUNTS; do
DOCKER_RUN_CMD="$DOCKER_RUN_CMD -v $mount"
done
fi
DOCKER_RUN_CMD="$DOCKER_RUN_CMD $IMAGE_TAG"
echo " 执行: $DOCKER_RUN_CMD"
eval $DOCKER_RUN_CMD
if [ $? -ne 0 ]; then
echo "❌ 容器启动失败"
exit 1
fi
echo " ✅ 容器启动成功"
echo ""
# 5. 等待容器启动并检查健康状态
echo "【5. 健康检查】"
sleep 5
CONTAINER_STATUS=$(docker inspect -f '{{.State.Status}}' "$CONTAINER_NAME" 2>/dev/null)
echo " 容器状态: $CONTAINER_STATUS"
if [ "$CONTAINER_STATUS" != "running" ]; then
echo " ❌ 容器未正常运行,查看日志:"
docker logs --tail 30 "$CONTAINER_NAME"
exit 1
fi
# 检查端口
if command -v curl &> /dev/null; then
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "http://127.0.0.1:${HOST_PORT}" 2>/dev/null)
echo " HTTP状态码: $HTTP_CODE"
fi
echo " ✅ 健康检查通过"
echo ""
# 6. 清理旧镜像
echo "【6. 清理旧镜像】"
IMAGE_COUNT=$(docker images "$IMAGE_NAME" --format '{{.Tag}}' | grep -v "latest" | wc -l)
echo " 当前镜像数: $IMAGE_COUNT"
if [ "$IMAGE_COUNT" -gt "$KEEP_IMAGES" ]; then
DELETE_COUNT=$((IMAGE_COUNT - KEEP_IMAGES))
echo " 清理 $DELETE_COUNT 个旧镜像..."
docker images "$IMAGE_NAME" --format '{{.Tag}} {{.CreatedAt}}' | grep -v "latest" | sort -k2 | head -n "$DELETE_COUNT" | awk '{print $1}' | while read tag; do
echo " 删除: ${IMAGE_NAME}:${tag}"
docker rmi "${IMAGE_NAME}:${tag}" 2>/dev/null
done
echo " ✅ 旧镜像已清理"
else
echo " 镜像数未超过保留数($KEEP_IMAGES),跳过"
fi
echo ""
# 7. 部署汇总
echo "========== 部署汇总 =========="
echo " 应用: $APP_NAME"
echo " Commit: $COMMIT_ID"
echo " 镜像: $IMAGE_TAG"
echo " 容器: $CONTAINER_NAME"
echo " 端口: ${HOST_PORT} -> ${CONTAINER_PORT}"
echo " 状态: $CONTAINER_STATUS"
echo " 访问地址: http://127.0.0.1:${HOST_PORT}"
echo ""
echo " 常用命令:"
echo " 查看日志: docker logs -f $CONTAINER_NAME"
echo " 进入容器: docker exec -it $CONTAINER_NAME /bin/bash"
echo " 重启容器: docker restart $CONTAINER_NAME"
echo " 停止容器: docker stop $CONTAINER_NAME"
echo ""
echo "========== 部署完成 =========="
适配环境
适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+
依赖环境:bash 4.0+
参数说明
[{"name": "APP_NAME", "label": "\u5e94\u7528\u540d\u79f0", "default": "myapp"}, {"name": "GIT_REPO", "label": "Git\u4ed3\u5e93\u5730\u5740", "default": "https://github.com/user/repo.git"}, {"name": "GIT_BRANCH", "label": "Git\u5206\u652f", "default": "main"}, {"name": "HOST_PORT", "label": "\u4e3b\u673a\u7aef\u53e3", "default": "8080"}, {"name": "CONTAINER_PORT", "label": "\u5bb9\u5668\u7aef\u53e3", "default": "80"}]