Docker自动化部署实战:从Git提交到生产发布的CI/CD流水线搭建

CI/CD流水线的核心环节

一条完整的CI/CD流水线覆盖代码提交到生产发布全流程:代码检出到单元测试到构建Docker镜像到推送镜像仓库到部署到目标环境。用Jenkins + Docker Registry + Shell脚本即可搭建一套轻量但可靠的自动化部署体系。

Jenkins环境与Docker Registry准备

Jenkins推荐用Docker方式部署,避免污染宿主环境:

# 部署Jenkins
docker run -d --name jenkins \
  -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/bin/docker:/usr/bin/docker \
  --restart=always jenkins/jenkins:lts

# 部署私有Docker Registry
docker run -d --name registry \
  -p 5000:5000 \
  -v registry_data:/var/lib/registry \
  --restart=always registry:2

Jenkins容器挂载Docker.sock是关键操作,这样Jenkins任务才能直接执行docker build和docker push。

项目Dockerfile编写规范

Spring Boot项目的多阶段构建Dockerfile:

# 构建阶段
FROM eclipse-temurin:17-jdk AS builder
WORKDIR /build
COPY pom.xml .
COPY src ./src
RUN ./mvnw package -DskipTests

# 运行阶段
FROM eclipse-temurin:17-jre
WORKDIR /app
COPY --from=builder /build/target/*.jar app.jar

ENV JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC"
EXPOSE 8080

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

多阶段构建让最终镜像只包含JRE和jar包,体积从700MB+降到200MB左右。不要把Maven缓存和源码打进运行镜像。

Jenkins Pipeline脚本:自动化构建与部署

在项目根目录创建Jenkinsfile:

pipeline {
    agent any
    environment {
        REGISTRY = '192.168.1.100:5000'
        IMAGE_NAME = "${REGISTRY}/${JOB_NAME}"
        TAG = "${BUILD_NUMBER}"
    }
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://git.example.com/project.git'
            }
        }
        stage('Test') {
            steps {
                sh './mvnw test'
            }
        }
        stage('Build Image') {
            steps {
                sh "docker build -t ${IMAGE_NAME}:${TAG} ."
                sh "docker tag ${IMAGE_NAME}:${TAG} ${IMAGE_NAME}:latest"
            }
        }
        stage('Push Registry') {
            steps {
                sh "docker push ${IMAGE_NAME}:${TAG}"
                sh "docker push ${IMAGE_NAME}:latest"
            }
        }
        stage('Deploy') {
            steps {
                sh """
                    ssh deploy@prod-server \
                      "docker pull ${IMAGE_NAME}:${TAG} && \
                       docker stop ${JOB_NAME} || true && \
                       docker rm ${JOB_NAME} || true && \
                       docker run -d --name ${JOB_NAME} \
                         -p 8080:8080 \
                         --restart=always \
                         ${IMAGE_NAME}:${TAG}"
                """
            }
        }
    }
    post {
        failure {
            echo 'Pipeline failed, check logs above'
        }
        success {
            echo "Deployed ${IMAGE_NAME}:${TAG} successfully"
        }
    }
}

回滚策略:每个版本都有迹可查

每次部署用BUILD_NUMBER做镜像Tag,回滚只需拉取上一个Tag重新run:

# 查看历史镜像Tag
docker images 192.168.1.100:5000/myapp --format "{{.Tag}} {{.CreatedAt}}"

# 回滚到指定版本
ssh deploy@prod-server "docker pull 192.168.1.100:5000/myapp:28 && \
    docker stop myapp && docker rm myapp && \
    docker run -d --name myapp -p 8080:8080 \
      --restart=always 192.168.1.100:5000/myapp:28"

保留最近10个版本的镜像,定期清理更早的Tag。私有Registry配合垃圾回收释放磁盘空间:

docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml

健康检查与自动重启

在docker run中加入健康检查,异常退出时自动恢复:

docker run -d --name myapp \
  -p 8080:8080 \
  --health-cmd="curl -f http://localhost:8080/actuator/health || exit 1" \
  --health-interval=30s \
  --health-retries=3 \
  --health-timeout=10s \
  --restart=always \
  192.168.1.100:5000/myapp:latest

三次健康检查失败后容器状态变为unhealthy,配合–restart=always策略,Docker守护进程会自动重启容器。配合Prometheus监控告警,实现故障秒级发现。

常见问题处理

Q: docker push到私有Registry报TLS错误?
在客户端/etc/docker/daemon.json中添加insecure-registries配置,然后重启dockerd。

Q: Jenkins构建时docker命令权限不够?
把jenkins用户加入docker用户组:usermod -aG docker jenkins,然后重启Jenkins容器。

Q: 镜像体积太大推送超时?
检查是否误把node_modules或target目录打入镜像,.dockerignore文件排除构建缓存目录。切换到多阶段构建后体积会大幅缩小。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/docker-zi-dong-hua-bu-shu-shi-zhan-cong-git-ti-jiao-dao/

(0)
小编小编
上一篇 12小时前
下一篇 12小时前

相关推荐