以下方案给出一套基于 Jenkins 的自动化打包与 Docker 部署流水线,聚焦 标准化、可回滚、安全 与 高效交付。内容直击落地细节,拿去即用。🚀


一、总体蓝图(先看全局)

  • 触发:Git Push / PR 合并 / 定时器

  • 构建:多阶段 Dockerfile → 生成不可变镜像(Tag:app:branch-commit-时间戳

  • 质量闸门:单元测试、镜像体积与漏洞扫描

  • 交付:推送镜像仓库 → 部署主机拉取 → docker compose/docker run 更新

  • 回滚:一键回滚到上一个稳定 Tag

关键成功因素:流水线即代码(Jenkinsfile)、凭证隔离、灰度与回滚。


二、标准 Dockerfile(多阶段、非 root、安全硬化)

# 构建阶段
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
RUN npm run build

# 运行阶段(静态站或前后端皆可按需调整)
FROM nginx:1.27-alpine
RUN addgroup -g 101 web && adduser -D -H -u 101 -G web web
COPY --from=builder /app/dist/ /usr/share/nginx/html/
COPY deploy/nginx.conf /etc/nginx/nginx.conf
USER 101
EXPOSE 8080
CMD ["nginx","-g","daemon off;"]

解释

  • 多阶段减少镜像体积,只带运行必需品。

  • USER 101 实现非 root运行,降低攻击面。

  • --mount=type=cache 充分利用构建缓存,加速 CI。


三、Jenkinsfile(声明式 Pipeline · 企业强化版)

pipeline {
  agent any
  environment {
    REGISTRY    = "registry.example.com"
    APP_NAME    = "demo-app"
    COMMIT      = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
    TS          = sh(returnStdout: true, script: 'date +%Y%m%d%H%M%S').trim()
    IMAGE_TAG   = "${REGISTRY}/${APP_NAME}:${BRANCH_NAME}-${COMMIT}-${TS}"
    LATEST_TAG  = "${REGISTRY}/${APP_NAME}:${BRANCH_NAME}-latest"
  }
  options { timestamps(); buildDiscarder(logRotator(numToKeepStr: '20')) }
  triggers { pollSCM('@daily') } // 可改为 webhook 或 cron
  stages {
    stage('Checkout') {
      steps {
        checkout scm
      }
    }
    stage('Unit Test') {
      steps {
        sh 'npm ci && npm test -- --ci'
      }
    }
    stage('Build Image') {
      steps {
        sh """
          docker build \
            --build-arg BUILDKIT_INLINE_CACHE=1 \
            -t ${IMAGE_TAG} -t ${LATEST_TAG} .
        """
      }
    }
    stage('Security Scan') {
      steps {
        // 如使用 trivy/grype,自行安装后启用
        sh "echo 'skip or run your image scan here'"
      }
    }
    stage('Push Image') {
      environment { DOCKER_CONFIG = "${env.WORKSPACE}/.docker" }
      steps {
        withCredentials([usernamePassword(credentialsId: 'docker-reg-cred', usernameVariable: 'U', passwordVariable: 'P')]) {
          sh """
            mkdir -p \$DOCKER_CONFIG
            echo "{\\"auths\\":{\\"${REGISTRY}\\":{\\"auth\\":\\"$(echo -n $U:$P | base64)\\"}}}" > \$DOCKER_CONFIG/config.json
            docker push ${IMAGE_TAG}
            docker push ${LATEST_TAG}
          """
        }
      }
    }
    stage('Deploy to Prod') {
      when { branch 'main' }
      steps {
        // 通过 SSH 到部署机执行 compose 更新(也可用 Jenkins Agent/Ansible)
        withCredentials([sshUserPrivateKey(credentialsId: 'deploy-ssh', keyFileVariable: 'KEY')]) {
          sh """
            ssh -o StrictHostKeyChecking=no -i $KEY deploy@prod '
              export IMAGE=${IMAGE_TAG} &&
              cd /opt/${APP_NAME} &&
              docker compose pull app &&
              docker compose up -d app &&
              docker image prune -f
            '
          """
        }
      }
    }
  }
  post {
    success {
      echo "Deployed: ${IMAGE_TAG}"
    }
    failure {
      echo "Build failed. See logs."
    }
  }
}

解释

  • environment 统一拼接镜像 Tag,保证可追溯可回滚

  • withCredentials 使用 Jenkins 凭证,避免泄露用户名/Token。

  • docker compose up -d app 实现无感升级;失败可快速拉起旧 Tag 回滚。


四、部署主机 docker-compose.yml(最小可行)

services:
  app:
    image: registry.example.com/demo-app:main-latest
    container_name: demo-app
    ports:
      - "80:8080"
    restart: unless-stopped

解释

  • 默认拉取 main-latest,生产发布由 Jenkins 替换为具体版本 Tag,回滚时只需切换回上一个 Tag。


五、流水线流程图(支持 Markdown/Vditor)

flowchart LR
A[开发提交代码] --> B[触发Jenkins Pipeline]
B --> C[单元测试/质量闸门]
C --> D[构建Docker镜像]
D --> E[安全扫描/体积校验]
E --> F[推送镜像仓库]
F --> G[部署机拉取新镜像]
G --> H[docker compose 滚动更新]
H --> I{探针健康?}
I -- 否 --> J[回滚上一稳定Tag]
I -- 是 --> K[完成发布]

六、关键参数选型对照(决策更快)

维度推荐值价值风险与对策
镜像构建多阶段体积小、面更小确保运行层仅带需要文件
运行用户非 root降低入侵面目录权限预先准备
Tag 策略分支+Commit+时间戳可追溯、可回滚规范化发布流程
部署方式compose / K8s快速落地 / 弹性治理先选简单、后扩展
凭证管理Jenkins Credentials合规与隔离定期轮换、最小权限
健康检查/healthz稳定上线不要过重逻辑

七、运维命令(常用即刻生效)

# 本地验证构建
docker build -t demo:local .

# 推送与登录(仅示例,正式走 Jenkins 凭证)
docker login registry.example.com
docker push registry.example.com/demo-app:dev-latest

# 快速回滚(在部署机)
docker pull registry.example.com/demo-app:main-<旧Tag>
docker stop demo-app && docker rm demo-app
docker run -d --name demo-app -p 80:8080 registry.example.com/demo-app:main-<旧Tag>

解释

  • 本地先跑通,减少 CI 反复;生产回滚始终以稳定 Tag 为锚点。


八、质量门槛(上线前自检✅)

  • 单测通过率 ≥ 90%,关键链路必须覆盖。

  • 镜像体积可控(前端/Java/Go 参考线不同),无高危漏洞

  • 不可变镜像:禁止在运行节点构建。

  • 发布与回滚脚本化,不可手工改容器。

  • 日志、告警、健康探针齐活,支持复盘。


九、两条硬结论

  1. 流水线即制度:把构建、扫描、部署都写进 Jenkinsfile,避免“口口相传式配置”。

  2. Tag 即版本:所有对外发布都落到明确 Tag,才能快、稳、可回滚。🎯

收尾:从今天起,把 CI/CD 当作产品化资产运营;让每一次上线都做到 可预测、可审计、可回滚。

更多推荐