From e12ce5c63267abf13f8726d6d28b0596a9e630b0 Mon Sep 17 00:00:00 2001 From: root <1772105645@qq.com> Date: Fri, 19 Dec 2025 10:26:34 +0800 Subject: [PATCH] Enhance logging for better troubleshooting and debugging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🔧 CI/CD Pipeline Improvements: - Added comprehensive logging with emojis for better readability - Detailed environment information display - Step-by-step progress tracking with timestamps - Enhanced Docker build progress with --progress=plain - Container deployment validation and health checks - Network connectivity testing and port monitoring - Storage usage reporting and cleanup operations 🏗️ Dockerfile Enhancements: - Added verbose logging for every build stage - Go environment verification and dependency tracking - Detailed compilation progress with file sizes - Runtime environment preparation checks - Built-in health check configuration - Enhanced startup logging with service URLs - Error-friendly fallback messages 📊 Debugging Features: - Build log preservation (build.log file) - Container state inspection and JSON formatting - Port listening status verification - Service availability testing with retries - Comprehensive error reporting with context - Container ID tracking for reference 🎯 Key Benefits: - Easy problem identification during CI/CD - Clear visibility into build and deployment process - Service health monitoring and validation - Streamlined troubleshooting workflow - Professional logging presentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .gitlab-ci.yml | 175 ++++++++++++++++++++++++++++++++++++++++--------- Dockerfile | 139 +++++++++++++++++++++++++++++++++++---- 2 files changed, 271 insertions(+), 43 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 22cfd12..60db75a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,11 +14,53 @@ build_image: stage: build image: 192.168.1.154:31010/docker/alpine:latest script: + - echo "🔧 ===== 开始构建阶段 =====" + - echo "📋 构建环境信息:" + - echo " - 工作目录: $(pwd)" + - echo " - 镜像名称: $DOCKER_IMAGE_NAME:$DOCKER_TAG" + - echo " - 私有仓库: $CI_REGISTRY" + - echo " - Git提交: $CI_COMMIT_SHORT_SHA" + - echo " - 构建时间: $(date)" + + - echo "" + - echo "📦 安装Docker CLI..." - apk add --no-cache docker-cli + + - echo "" + - echo "🔐 登录私有仓库..." - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - - docker build -t $DOCKER_IMAGE_NAME:$DOCKER_TAG . + - echo "✅ Docker登录成功" + + - echo "" + - echo "🔍 检查Dockerfile和项目文件..." + - ls -la + - echo "" + - echo "📄 Dockerfile内容预览:" + - head -20 Dockerfile + + - echo "" + - echo "🏗️ 开始构建Docker镜像..." + - echo " 构建命令: docker build -t $DOCKER_IMAGE_NAME:$DOCKER_TAG ." + - docker build --progress=plain --no-cache -t $DOCKER_IMAGE_NAME:$DOCKER_TAG . 2>&1 | tee build.log + + - echo "" + - echo "📊 构建结果检查..." + - docker images | grep $DOCKER_IMAGE_NAME + + - echo "" + - echo "🏷️ 标记镜像为私有仓库地址..." - docker tag $DOCKER_IMAGE_NAME:$DOCKER_TAG $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG + - echo "✅ 镜像标记完成: $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG" + + - echo "" + - echo "📤 推送镜像到私有仓库..." - docker push $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG + - echo "✅ 镜像推送成功" + + - echo "" + - echo "🎯 ===== 构建阶段完成 =====" + - echo "📋 构建产物信息:" + - docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}" | grep -E "(REPOSITORY|$DOCKER_IMAGE_NAME|$CI_REGISTRY)" only: - main @@ -32,22 +74,58 @@ deploy_service: DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: "/certs" script: - # 安装必要的工具 - - apk add --no-cache docker-cli wget - # 登录到私有仓库 + - echo "🚀 ===== 开始部署阶段 =====" + - echo "📋 部署环境信息:" + - echo " - 工作目录: $(pwd)" + - echo " - 镜像地址: $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG" + - echo " - Docker主机: $DOCKER_HOST" + - echo " - 部署时间: $(date)" + + - echo "" + - echo "📦 安装部署工具..." + - apk add --no-cache docker-cli wget curl + - echo "✅ 工具安装完成" + + - echo "" + - echo "🔐 登录私有仓库..." - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - # 拉取最新构建的镜像 + - echo "✅ Docker登录成功" + + - echo "" + - echo "🔍 检查Docker环境..." + - docker version + - echo "" + - echo "📋 当前Docker镜像列表:" + - docker images | head -10 + + - echo "" + - echo "📥 拉取最新构建的镜像..." + - echo " 拉取命令: docker pull $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG" - docker pull $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG - # 停止并删除旧容器 - - docker stop file-system-server 2>/dev/null || true - - docker rm file-system-server 2>/dev/null || true - # 删除旧镜像(释放空间) - - docker rmi $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG 2>/dev/null || true - # 创建日志目录 + - echo "✅ 镜像拉取完成" + + - echo "" + - echo "🧹 清理旧部署..." + - echo "🛑 停止现有容器..." + - docker stop file-system-server 2>/dev/null || echo " ℹ️ 没有运行中的容器" + - echo "🗑️ 删除现有容器..." + - docker rm file-system-server 2>/dev/null || echo " ℹ️ 没有现有容器" + - echo "🗑️ 清理旧镜像..." + - docker rmi $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG 2>/dev/null || echo " ℹ️ 没有旧镜像" + + - echo "" + - echo "📁 创建部署目录..." - mkdir -p /builds/root/file_service/logs - # 运行新的容器 + - echo "✅ 目录创建完成" + + - echo "" + - echo "🏃 运行新容器..." + - echo " 容器名称: file-system-server" + - echo " 端口映射: 8080:8080" + - echo " 镜像地址: $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG" + - | - docker run -d \ + CONTAINER_ID=$(docker run -d \ --name file-system-server \ --restart unless-stopped \ -p 8080:8080 \ @@ -66,25 +144,62 @@ deploy_service: --log-driver json-file \ --log-opt max-size=10m \ --log-opt max-file=3 \ - $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG + $CI_REGISTRY/$DOCKER_IMAGE_NAME:$DOCKER_TAG) + echo "✅ 容器启动成功,ID: $CONTAINER_ID" - # 等待容器启动 - - sleep 15 - # 显示容器状态 - - docker ps --filter "name=file-system-server" - # 显示容器健康状态 - - docker inspect --format='{{.State.Health.Status}}' file-system-server || echo "Health check not available yet" - # 显示容器日志(最近20行) - - docker logs --tail=20 file-system-server - # 验证服务是否正常响应 - - wget --no-verbose --tries=1 --spider http://localhost:8080/swagger/index.html || echo "Service health check failed" - # 清理未使用的镜像 + - echo "" + - echo "⏳ 等待容器启动..." + - for i in {1..15}; do echo -n "⏱️ 等待 $i/15 秒... "; sleep 1; done + - echo "" + + - echo "" + - echo "📊 容器状态检查..." + - docker ps --filter "name=file-system-server" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}\t{{.Image}}" + + - echo "" + - echo "🏥 容器健康状态..." + - HEALTH_STATUS=$(docker inspect --format='{{.State.Health.Status}}' file-system-server 2>/dev/null || echo "checking") + - echo " 健康状态: $HEALTH_STATUS" + + - echo "" + - echo "📋 容器详细信息..." + - docker inspect file-system-server --format='{{json .State}}' | jq '.' 2>/dev/null || docker inspect file-system-server --format='{{.State}}' + + - echo "" + - echo "📝 容器启动日志 (最近30行):" + - docker logs --tail=30 file-system-server + + - echo "" + - echo "🔍 服务连通性测试..." + - echo " 测试URL: http://localhost:8080/swagger/index.html" + - if wget --no-verbose --tries=3 --timeout=10 --spider http://localhost:8080/swagger/index.html; then + echo "✅ 服务连通性测试成功" + else + echo "❌ 服务连通性测试失败" + echo "📋 端口监听状态:" + - netstat -tlnp | grep :8080 || echo " 端口8080未监听" + fi + + - echo "" + - echo "🧹 清理未使用的镜像..." - docker image prune -f - # 显示最终状态 - - echo "🚀 部署完成!服务地址: http://localhost:8080" - - echo "📊 容器状态:" + + - echo "" + - echo "📋 部署最终报告..." + - echo "🎯 ===== 部署阶段完成 =====" + - echo "" + - echo "📊 服务信息:" + - echo " 🌐 服务地址: http://localhost:8080" + - echo " 📖 API文档: http://localhost:8080/swagger/index.html" + - echo " 📱 Web界面: http://localhost:8080/web" + - echo " 📋 容器名称: file-system-server" + - echo " 🏥 健康状态: $HEALTH_STATUS" + - echo "" + - echo "📋 容器运行状态:" - docker ps --filter "name=file-system-server" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" - - echo "📋 健康检查状态:" - - docker inspect --format='{{.State.Health.Status}}' file-system-server || echo "Pending..." + + - echo "" + - echo "💾 存储使用情况:" + - docker system df --format "table {{.Type}}\t{{.TotalCount}}\t{{.Size}}\t{{.Reclaimed}}" only: - main diff --git a/Dockerfile b/Dockerfile index d62bc82..5500816 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,39 +3,152 @@ FROM 192.168.1.154:31010/docker/alpine:latest AS builder WORKDIR /app -# Install Go -RUN apk add --no-cache go +# Install Go with verbose logging +RUN echo "🔧 ===== 安装Go环境 =====" && \ + echo "📦 更新Alpine包索引..." && \ + apk update && \ + echo "📦 安装Go语言环境..." && \ + apk add --no-cache go && \ + echo "✅ Go安装完成" && \ + go version && \ + echo "📋 Go环境信息:" && \ + which go && \ + go env GOOS GOARCH GOVERSION # Configure Go proxy for faster downloads ENV GOPROXY=https://goproxy.cn,direct ENV GOSUMDB=sum.golang.google.cn -# Copy go mod and sum files +RUN echo "🔧 ===== 配置Go代理 =====" && \ + echo "📡 Go代理配置:" && \ + go env GOPROXY && \ + go env GOSUMDB + +# Copy go mod and sum files with logging +RUN echo "🔧 ===== 复制依赖文件 =====" && \ + echo "📄 复制go.mod和go.sum..." + COPY go.mod go.sum ./ -# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed -RUN go mod download +RUN echo "📋 依赖文件内容:" && \ + echo "--- go.mod ---" && \ + head -20 go.mod && \ + echo "--- go.sum ---" && \ + wc -l go.sum && \ + echo "📦 总依赖数: $(cat go.sum | wc -l)" + +# Download all dependencies with verbose logging +RUN echo "🔧 ===== 下载Go依赖 =====" && \ + echo "⬇️ 开始下载依赖包..." && \ + go mod download -x && \ + echo "✅ 依赖下载完成" && \ + go mod verify && \ + echo "✅ 依赖验证完成" && \ + echo "📋 下载的模块:" && \ + go mod why -m all + +# Copy the source code with logging +RUN echo "🔧 ===== 复制源代码 =====" && \ + echo "📁 项目结构:" && \ + find . -type f -name "*.go" | head -10 -# Copy the source from the current directory to the Working Directory inside the container COPY . . -# Build the Go app -RUN go build -o server ./cmd/server +RUN echo "📋 复制完成后的目录结构:" && \ + ls -la && \ + echo "📊 源代码统计:" && \ + find . -name "*.go" | wc -l && \ + echo " Go文件数量: $(find . -name "*.go" | wc -l)" + +# Build the Go app with detailed logging +RUN echo "🔧 ===== 编译Go应用 =====" && \ + echo "🏗️ 开始编译..." && \ + echo "📋 编译信息:" && \ + echo " - 工作目录: $(pwd)" && \ + echo " - Go版本: $(go version)" && \ + echo " - 目标: ./cmd/server" && \ + echo "🏗️ 执行编译命令..." && \ + go build -v -o server ./cmd/server && \ + echo "✅ 编译完成" && \ + echo "📋 编译产物信息:" && \ + ls -la server && \ + file server && \ + echo "📏 二进制大小: $(ls -lh server | awk '{print $5}')" && \ + echo "🔍 可执行文件测试:" && \ + ./server --version 2>/dev/null || echo " (应用不支持--version参数)" # Run Stage FROM 192.168.1.154:31010/docker/alpine:latest WORKDIR /app -# Copy the Pre-built binary from the previous stage +RUN echo "🔧 ===== 运行时环境准备 =====" && \ + echo "📋 运行时环境信息:" && \ + echo " - 工作目录: $(pwd)" && \ + echo " - 用户: $(whoami)" && \ + echo " - 系统信息: $(uname -a)" && \ + echo "📋 安装运行时工具..." && \ + apk add --no-cache wget && \ + echo "✅ 运行时环境准备完成" + +# Copy the Pre-built binary from the previous stage with logging +RUN echo "📦 ===== 复制构建产物 =====" && \ + echo "🔄 从构建阶段复制二进制文件..." + COPY --from=builder /app/server . -# Copy web resources + +RUN echo "✅ 二进制文件复制完成" && \ + ls -la server && \ + file server && \ + echo "🔍 测试二进制文件..." && \ + chmod +x server + +# Copy web resources with logging +RUN echo "📦 ===== 复制Web资源 =====" && \ + echo "🌐 复制web前端文件..." + COPY --from=builder /app/web ./web -# Copy docs + +RUN echo "✅ Web资源复制完成" && \ + echo "📁 Web目录结构:" && \ + (test -d web && (find web -type f | head -10) || echo " Web目录不存在") + +# Copy docs with logging +RUN echo "📦 ===== 复制文档文件 =====" && \ + echo "📚 复制API文档..." + COPY --from=builder /app/docs ./docs +RUN echo "✅ 文档复制完成" && \ + echo "📁 文档目录结构:" && \ + (test -d docs && (find docs -type f | head -5) || echo " 文档目录不存在") + +RUN echo "📋 最终运行环境文件列表:" && \ + ls -la && \ + echo "📊 目录大小统计:" && \ + du -sh * 2>/dev/null || echo " 无法获取大小信息" + # Expose port 8080 to the outside world EXPOSE 8080 -# Command to run the executable -CMD ["./server"] +# Add health check +RUN echo "🏥 ===== 配置健康检查 =====" && \ + echo "📋 健康检查配置:" && \ + echo " - 端口: 8080" && \ + echo " - 路径: /swagger/index.html" + +HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:8080/swagger/index.html || exit 1 + +# Command to run the executable with startup logging +CMD echo "🚀 ===== 启动文件系统服务 =====" && \ + echo "📋 启动信息:" && \ + echo " - 工作目录: $(pwd)" && \ + echo " - 可执行文件: $(ls -la server)" && \ + echo " - 端口: 8080" && \ + echo " - 启动时间: $(date)" && \ + echo "🌐 服务即将启动..." && \ + echo "📖 API文档地址: http://localhost:8080/swagger/index.html" && \ + echo "📱 Web界面地址: http://localhost:8080/web" && \ + echo "🚀 ===== 开始运行服务 =====" && \ + ./server