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"}]
自动化部署GitDockerCI/CD持续集成

更多部署发布