Docker集成 #

本节介绍如何在Jenkins Pipeline中集成Docker,实现容器化构建和部署。

Docker插件安装 #

text
插件名称: Docker Pipeline
插件ID: docker-workflow

Docker Agent #

使用Docker镜像作为Agent #

groovy
pipeline {
    agent {
        docker {
            image 'maven:3.8-openjdk-11'
            args '-v $HOME/.m2:/root/.m2'
        }
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
    }
}

使用Dockerfile #

groovy
pipeline {
    agent {
        dockerfile {
            filename 'Dockerfile.build'
            dir 'docker'
        }
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
    }
}

Docker构建 #

构建镜像 #

groovy
stage('Build Image') {
    steps {
        script {
            docker.build('myapp:${BUILD_NUMBER}')
        }
    }
}

带参数构建 #

groovy
stage('Build Image') {
    steps {
        script {
            docker.build('myapp:${BUILD_NUMBER}', 
                '--build-arg VERSION=${BUILD_NUMBER} ' +
                '--build-arg ENV=production .'
            )
        }
    }
}

多阶段构建 #

groovy
stage('Build Image') {
    steps {
        script {
            docker.build('myapp:${BUILD_NUMBER}', 
                '--target production .'
            )
        }
    }
}

Docker推送 #

推送到仓库 #

groovy
stage('Push Image') {
    steps {
        script {
            docker.withRegistry('https://registry.example.com', 'docker-credentials') {
                docker.image('myapp:${BUILD_NUMBER}').push()
                docker.image('myapp:${BUILD_NUMBER}').push('latest')
            }
        }
    }
}

推送到Docker Hub #

groovy
stage('Push to Docker Hub') {
    steps {
        script {
            docker.withRegistry('', 'docker-hub-credentials') {
                docker.image('username/myapp:${BUILD_NUMBER}').push()
            }
        }
    }
}

Docker Compose #

启动服务 #

groovy
stage('Integration Test') {
    steps {
        sh 'docker-compose -f docker-compose.test.yml up -d'
        sh 'npm run test:integration'
        sh 'docker-compose -f docker-compose.test.yml down'
    }
}

使用withDockerCompose #

groovy
stage('Integration Test') {
    steps {
        withDockerCompose(file: 'docker-compose.test.yml') {
            sh 'npm run test:integration'
        }
    }
}

Docker in Docker #

配置 #

groovy
pipeline {
    agent {
        docker {
            image 'docker:latest'
            args '-v /var/run/docker.sock:/var/run/docker.sock'
        }
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'docker build -t myapp .'
            }
        }
    }
}

安全考虑 #

text
Docker in Docker需要:
- 挂载docker.sock
- 给予容器docker权限
- 注意安全风险

完整示例 #

groovy
pipeline {
    agent any
    
    environment {
        APP_NAME = 'myapp'
        DOCKER_REGISTRY = 'registry.example.com'
    }
    
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        
        stage('Build Image') {
            steps {
                script {
                    echo 'Building Docker image...'
                    docker.build("${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}")
                }
            }
        }
        
        stage('Test Image') {
            steps {
                script {
                    docker.image("${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}").inside {
                        sh 'npm test'
                    }
                }
            }
        }
        
        stage('Push Image') {
            steps {
                script {
                    docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-credentials') {
                        docker.image("${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}").push()
                        docker.image("${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}").push('latest')
                    }
                }
            }
        }
        
        stage('Deploy') {
            steps {
                sh """
                    kubectl set image deployment/${APP_NAME} \
                        ${APP_NAME}=${DOCKER_REGISTRY}/${APP_NAME}:${BUILD_NUMBER}
                """
            }
        }
    }
    
    post {
        always {
            sh 'docker image prune -f'
        }
    }
}

最佳实践 #

1. 使用多阶段构建 #

dockerfile
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]

2. 使用构建缓存 #

groovy
docker.build('myapp:${BUILD_NUMBER}', 
    '--cache-from registry.example.com/myapp:latest .'
)

3. 清理镜像 #

groovy
post {
    always {
        sh 'docker image prune -f'
    }
}

4. 镜像标签策略 #

groovy
docker.image('myapp').push("${BUILD_NUMBER}")
docker.image('myapp').push('latest')
docker.image('myapp').push("${GIT_COMMIT.substring(0, 7)}")

小结 #

  • Docker Agent使用容器作为构建环境
  • docker.build构建镜像
  • docker.withRegistry推送到仓库
  • 支持Docker Compose集成
  • 注意Docker in Docker安全风险
最后更新:2026-03-28