Jenkins入门教程(九):Jenkins与Docker集成
Docker为Jenkins提供了灵活的构建环境,本文将详细介绍如何在Jenkins中使用Docker,包括完整的配置步骤和Pipeline示例。
安装Docker插件
在插件管理中安装以下Docker相关插件:
- Docker Pipeline:在Pipeline中使用Docker
- Docker:Docker API集成
- Docker Commons:Docker共享功能
配置Docker环境
确保Jenkins服务器上安装了Docker,并且Jenkins用户有权限运行Docker命令:
# 安装Docker
curl -fsSL https://get.docker.com | sh
# 将Jenkins用户添加到docker组
sudo usermod -aG docker jenkins
# 重启Jenkins服务
sudo systemctl restart jenkins
# 验证Docker权限
sudo -u jenkins docker ps
在Docker容器中构建
使用agent docker指令可以在Docker容器中执行构建:
pipeline {
agent {
docker {
image 'maven:3.8-openjdk-17'
args '-v /root/.m2:/root/.m2' // 缓存Maven依赖
}
}
stages {
stage('Check Environment') {
steps {
sh '''
echo "Java Version:"
java -version
echo ""
echo "Maven Version:"
mvn -version
'''
}
}
stage('Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
}
}
}
执行结果:
[Pipeline] { (Check Environment)
[Pipeline] sh
+ echo 'Java Version:'
Java Version:
+ java -version
openjdk version "17.0.9" 2023-10-17
OpenJDK Runtime Environment (build 17.0.9+9)
OpenJDK 64-Bit Server VM (build 17.0.9+9, mixed mode, sharing)
+ echo 'Maven Version:'
Maven Version:
+ mvn -version
Apache Maven 3.8.7 (b89d5959fcde851dcb1c8946a785a163f14e1e29)
Maven home: /usr/share/maven
Java version: 17.0.9, vendor: Eclipse Adoptium
构建Docker镜像
在Pipeline中构建和推送Docker镜像:
pipeline {
agent any
environment {
DOCKER_REGISTRY = 'registry.example.com'
IMAGE_NAME = 'my-app'
IMAGE_TAG = "${env.BUILD_NUMBER}"
}
stages {
stage('Build Application') {
agent {
docker {
image 'maven:3.8-openjdk-17'
args '-v /root/.m2:/root/.m2'
}
}
steps {
sh 'mvn clean package -DskipTests'
stash includes: 'target/*.jar', name: 'app-jar'
}
}
stage('Build Docker Image') {
steps {
unstash 'app-jar'
script {
// 使用docker.build构建镜像
def image = docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}")
echo "Built image: ${image.id}"
}
}
}
stage('Push to Registry') {
steps {
script {
docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-registry-creds') {
def image = docker.image("${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}")
image.push()
image.push('latest')
}
}
}
}
}
post {
always {
// 清理本地镜像
sh "docker rmi ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} || true"
}
}
}
示例Dockerfile
项目根目录的Dockerfile:
# 多阶段构建
FROM maven:3.8-openjdk-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests
# 运行时镜像
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Docker Compose集成
对于多容器应用,使用docker-compose:
pipeline {
agent any
stages {
stage('Start Services') {
steps {
sh '''
docker-compose -f docker-compose.test.yml up -d
# 等待服务启动
sleep 10
# 检查服务状态
docker-compose -f docker-compose.test.yml ps
'''
}
}
stage('Run Integration Tests') {
steps {
sh '''
# 执行集成测试
docker-compose -f docker-compose.test.yml exec -T app ./run-tests.sh
'''
}
}
stage('Collect Logs') {
steps {
sh 'docker-compose -f docker-compose.test.yml logs > docker-logs.txt'
archiveArtifacts artifacts: 'docker-logs.txt', allowEmptyArchive: true
}
}
}
post {
always {
sh '''
docker-compose -f docker-compose.test.yml down -v
docker system prune -f
'''
}
}
}
Docker Registry认证
配置Docker Registry凭据:
- 在Jenkins凭据中添加用户名密码凭据,ID为docker-registry-creds
- 在Pipeline中使用withRegistry块
// Docker Hub
docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-creds') {
def image = docker.build('myuser/myapp:latest')
image.push()
}
// 私有Registry
docker.withRegistry('https://registry.example.com', 'private-registry-creds') {
def image = docker.build('registry.example.com/myapp:latest')
image.push()
}
// AWS ECR
docker.withRegistry('https://123456789.dkr.ecr.us-east-1.amazonaws.com', 'ecr:us-east-1:aws-creds') {
def image = docker.build('123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:latest')
image.push()
}
DinD vs DooD
两种在容器中使用Docker的方式:
- DinD (Docker in Docker):在容器内运行完整Docker守护进程,隔离性好但开销大
- DooD (Docker outside of Docker):共享宿主机的Docker socket,更轻量(推荐)
# Docker运行Jenkins时挂载socket (DooD)
docker run -d \
--name jenkins \
-v /var/run/docker.sock:/var/run/docker.sock \
-v jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts
最佳实践
- 使用多阶段构建减小镜像体积
- 使用.dockerignore排除不需要的文件
- 固定基础镜像版本,避免使用latest
- 定期清理无用镜像释放空间
- 为生产镜像打上版本标签
总结
本文详细介绍了Jenkins与Docker的集成方法,包括在容器中构建、构建Docker镜像、使用Docker Compose等。Docker让构建环境标准化,是现代CI/CD的重要组成部分。
下一篇我们将学习使用Jenkins构建Java/Maven项目。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。







