From 60fcec6994fa73d8427262c0fc9ae001f11b0f3d Mon Sep 17 00:00:00 2001 From: wangtianqi <1350217033@qq.com> Date: Wed, 25 Jun 2025 14:05:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 71 ++++++++++++++++++++-------------------------------- Jenkinsfile | 72 +++++++++++------------------------------------------ 2 files changed, 41 insertions(+), 102 deletions(-) diff --git a/Dockerfile b/Dockerfile index 537950c..3f4239d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,54 +1,37 @@ -# 构建阶段 -FROM golang:1.21-alpine AS builder - -# 设置工作目录 -WORKDIR /app - -# 安装依赖 -RUN apk add --no-cache git ca-certificates tzdata - -# 复制go mod文件 -COPY go.mod go.sum ./ - -# 下载依赖 -RUN go mod download - -# 复制源代码 -COPY . . - -# 设置构建参数 -ARG BUILD_TIME -ARG GIT_COMMIT - -# 构建应用 -RUN CGO_ENABLED=0 GOOS=linux go build \ - -ldflags="-w -s -X main.buildTime=${BUILD_TIME} -X main.gitCommit=${GIT_COMMIT}" \ - -o main . - -# 运行阶段 +# 参考Java项目的成功模式:使用单阶段构建,直接复制Jenkins已构建的二进制文件 FROM alpine:latest -# 安装ca证书 -RUN apk --no-cache add ca-certificates tzdata +# 安装必要工具(curl用于健康检查,ca-certificates用于HTTPS请求) +RUN apk add --no-cache curl ca-certificates tzdata -WORKDIR /root/ - -# 从builder阶段复制二进制文件 -COPY --from=builder /app/main . - -# 复制配置文件(可选) -COPY --from=builder /app/.env . +# 设置时区 +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 创建非root用户 -RUN adduser -D -s /bin/sh appuser -USER appuser +RUN addgroup -g 1000 goapp && adduser -u 1000 -G goapp -s /bin/sh -D goapp + +# 创建应用目录 +WORKDIR /app + +# 直接复制已构建的二进制文件(在Jenkins中已经通过go build构建完成) +COPY golang-demo . + +# 复制配置文件(如果存在) +COPY .env* ./ + +# 创建日志目录并设置权限 +RUN mkdir -p /app/logs && chown -R goapp:goapp /app && chmod +x /app/golang-demo + +# 切换到非root用户 +USER goapp # 暴露端口 EXPOSE 8080 -# 健康检查 -HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1 +# 健康检查 - 使用Go应用的标准端点 +HEALTHCHECK --interval=30s --timeout=3s --start-period=30s --retries=3 \ + CMD curl -f http://localhost:8080/health || curl -f http://localhost:8080/ping || exit 1 -# 运行应用 -CMD ["./main"] \ No newline at end of file +# 启动应用 +ENTRYPOINT ["./golang-demo"] \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile index 50ff8c1..8b6beb0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,11 +1,5 @@ pipeline { - // 使用Docker代理来提供稳定的Go环境,避免网络下载问题 - agent { - docker { - image 'golang:1.21-alpine' - args '-v /var/run/docker.sock:/var/run/docker.sock' - } - } + agent any options { buildDiscarder(logRotator(numToKeepStr: '10')) @@ -13,6 +7,10 @@ pipeline { timestamps() } + tools { + go 'go' // 使用Jenkins配置的Go工具 + } + environment { // 目标服务器配置 DEPLOY_SERVER = '116.62.163.84' @@ -33,22 +31,6 @@ pipeline { } stages { - stage('环境准备') { - steps { - echo '🔧 准备Docker环境...' - sh ''' - # 安装Docker客户端和其他必要工具 - apk add --no-cache docker-cli curl wget git ca-certificates tzdata - - # 验证Go和Docker环境 - go version - docker --version - - echo "✅ 环境准备完成" - ''' - } - } - stage('Checkout') { steps { echo '🔄 开始检出代码...' @@ -59,14 +41,8 @@ pipeline { script: "git rev-parse --short HEAD", returnStdout: true ).trim() - - env.BUILD_TIME = sh( - script: 'date -u +"%Y-%m-%dT%H:%M:%SZ"', - returnStdout: true - ).trim() } echo "📋 Git提交ID: ${env.GIT_COMMIT_SHORT}" - echo "⏰ 构建时间: ${env.BUILD_TIME}" } } @@ -81,23 +57,11 @@ pipeline { echo "=== Go环境信息 ===" go env - echo "=== 验证Go工具路径 ===" - which go - echo "GOROOT: $GOROOT" - echo "GOPATH: $GOPATH" - echo "PATH: $PATH" - echo "=== Docker版本 ===" docker --version echo "=== 工作目录 ===" pwd && ls -la - - echo "=== Go模块信息 ===" - cat go.mod - - echo "=== 验证Go模块可用性 ===" - go mod verify || echo "模块验证跳过(首次运行)" ''' echo "✅ 构建环境检查完成" @@ -219,11 +183,10 @@ EOF sh ''' echo "开始编译..." CGO_ENABLED=0 GOOS=linux go build \\ - -ldflags="-w -s -X main.buildTime=${BUILD_TIME} -X main.gitCommit=${GIT_COMMIT_SHORT}" \\ + -ldflags="-w -s -X main.gitCommit=${GIT_COMMIT_SHORT}" \\ -o golang-demo . echo "验证二进制文件..." - file golang-demo ls -lh golang-demo echo "✅ 编译完成" @@ -243,7 +206,6 @@ EOF stage('构建Docker镜像') { steps { echo '🐳 构建Docker镜像...' - echo '💡 提示:通过Docker socket在容器内访问主机Docker守护进程' script { try { // 清理旧镜像 @@ -251,16 +213,15 @@ EOF echo "开始构建Docker镜像: ${IMAGE_NAME}:${IMAGE_TAG}" - // 构建Docker镜像 + // 使用传统Docker构建,参考Java项目的成功模式 timeout(time: 20, unit: 'MINUTES') { sh """ - # 构建Docker镜像,传入构建参数 - docker build \\ - --build-arg BUILD_TIME="${BUILD_TIME}" \\ - --build-arg GIT_COMMIT="${GIT_COMMIT_SHORT}" \\ - -t ${IMAGE_NAME}:${IMAGE_TAG} \\ - -t ${IMAGE_NAME}:latest . + # 确保二进制文件存在并有执行权限 + ls -la golang-demo + chmod +x golang-demo + # 使用传统Docker构建(无需构建参数,直接复制已编译文件) + docker build -t ${IMAGE_NAME}:${IMAGE_TAG} -t ${IMAGE_NAME}:latest . echo "✅ Docker镜像构建完成" # 验证镜像 @@ -360,7 +321,6 @@ EOF -p ${deployPort}:8080 \\ --restart unless-stopped \\ -e GIN_MODE=release \\ - -e ENVIRONMENT=${environment} \\ ${IMAGE_NAME}:${IMAGE_TAG} # 清理临时文件 @@ -387,9 +347,9 @@ EOF // 等待应用启动 sleep(time: 30, unit: 'SECONDS') - def deployPort = '15020' + def deployPort = '15021' if (env.BRANCH_NAME == 'develop' || env.BRANCH_NAME?.startsWith('feature/')) { - deployPort = '15021' + deployPort = '15022' } try { @@ -480,12 +440,9 @@ EOF 🔢 构建号: ${env.BUILD_NUMBER} 🌿 分支: ${env.BRANCH_NAME ?: 'unknown'} 📝 提交: ${env.GIT_COMMIT_SHORT ?: 'unknown'} -⏰ 构建时间: ${env.BUILD_TIME ?: 'unknown'} ⏱️ 持续时间: ${currentBuild.durationString} 🔗 构建链接: ${env.BUILD_URL} 🌐 应用地址: http://${DEPLOY_SERVER}:${deployPort} -🏥 健康检查: http://${DEPLOY_SERVER}:${deployPort}/health -🏓 Ping测试: http://${DEPLOY_SERVER}:${deployPort}/ping """ echo message @@ -502,7 +459,6 @@ EOF 🔢 构建号: ${env.BUILD_NUMBER} 🌿 分支: ${env.BRANCH_NAME ?: 'unknown'} 📝 提交: ${env.GIT_COMMIT_SHORT ?: 'unknown'} -⏰ 构建时间: ${env.BUILD_TIME ?: 'unknown'} ⏱️ 持续时间: ${currentBuild.durationString} 🔗 构建链接: ${env.BUILD_URL} 📄 查看日志: ${env.BUILD_URL}console