Jenkins パイプライン: Docker コンテナ内で Docker をビルドする

Jenkins パイプライン: Docker コンテナ内で Docker をビルドする

私は次のことをやろうとしています

  1. コードを確認する
  2. 他の Docker イメージを使用して事前チェックを実行します (Jenkins ノードにこれらをインストールしたくない)
  3. dockerイメージを使用してjarをビルドするmaven:3.6-jdk-8
  4. 次にDockerfile実行してアプリイメージをビルドします
  5. イメージをリポジトリにプッシュする

現在、Jenkins ノードに Docker 以外のものをインストールしたくありません。これを実現するには、Docker コンテナで完全なパイプラインを実行したいです。私が苦労しているのは、コンテナ内から 4 番目のステップを構築する方法です。

私はJenkinsfileを以下のように書きました

pipeline {

    agent none
    
    stages {
        stage('Maven build') {
            agent {
                docker {
                    image 'maven:3.6-jdk-8'
                    args '-u root:root'
                }
            }
            steps {
                checkout(
                    [
                        $class: 'GitSCM',
                        branches: [
                            [name: '*/master']
                        ],
                        doGenerateSubmoduleConfigurations: false, 
                        extensions: [], 
                        submoduleCfg: [], 
                        userRemoteConfigs: [
                            [
                                credentialsId: '<cred-id>',
                                url: '<github-url>']
                            ]
                        ])
                        
                sh '''
                    set -eux pipefail

                    mvn -e clean install
                '''
            }
        }
        stage('Build docker image') {
             // Which docker image to use?
        }
    }
}

しかし、コンテナ内で Docker イメージを構築する方法がわかりません。検索してもあまり役に立ちませんでした。Docker イメージの構築に Jenkins ノードを使用しようとしましたが、組み合わせることはできないようです。これはかなり未解決の質問であることは完全に理解していますが、わかりやすい答えがわかれば役立つと思います。

答え1

私は次のようなことを試してみます:

pipeline {

    /*
     * Run everything on an existing agent configured with a label 'docker'.
     * This agent will need docker, git and a jdk installed at a minimum.
     */
    agent {
        node {
            label 'docker'
        }
    }

    // using the Timestamper plugin we can add timestamps to the console log
    options {
        timestamps()
    }

    environment {
        //Use Pipeline Utility Steps plugin to read information from pom.xml into env variables
        IMAGE = readMavenPom().getArtifactId()
        VERSION = readMavenPom().getVersion()
    }
    
    stages {

        stage('Clone repository') {
            /* 
             * Let's make sure we have the repository cloned to our workspace 
             */
            checkout(
                    [
                        $class: 'GitSCM',
                        branches: [
                            [name: '*/master']
                        ],
                        doGenerateSubmoduleConfigurations: false, 
                        extensions: [], 
                        submoduleCfg: [], 
                        userRemoteConfigs: [
                            [
                                credentialsId: '<cred-id>',
                                url: '<github-url>']
                            ]
                        ])
        }

        stage('Maven build') {
            agent {
                docker {
                    /*
                     * Reuse the workspace on the agent defined at top-level of
                     * Pipeline but run inside a container.
                     */
                    image 'maven:3.6-jdk-8'
                    reuseNode true
                }
            }
            steps {        
                sh '''
                    set -eux pipefail

                    mvn -e clean install
                '''
            }
            post {
                success {
                /* 
                 * Only worry about archiving the jar file 
                 * if the build steps are successful (this part may be not necessary)
                 */
                archiveArtifacts(artifacts: '**/target/*.jar', allowEmptyArchive: true)
                }
           }
        }
        stage('Build docker image') {
             steps {
                sh '''
                    docker build -t ${IMAGE} .
                    docker tag ${IMAGE} ${IMAGE}:${VERSION}
                    docker push ${IMAGE}:${VERSION}
                '''
            }
        }
    }
}

このreuseNodeオプションを使用すると、チェックアウトとDockerビルドがノード自体で実行される場合でも、コンテナ内でMavenビルドを実行できるようになります。ドキュメントを参照してください。ここ

関連情報