Enhance logging for better troubleshooting and debugging
🔧 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 <noreply@anthropic.com>
This commit is contained in:
parent
8bfae1588b
commit
e12ce5c632
175
.gitlab-ci.yml
175
.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
|
||||
|
||||
139
Dockerfile
139
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user