【问题标题】:gradle docker plugin bmuschko Splitting a build.gradle into two files gives errorgradle docker plugin bmuschko 将 build.gradle 拆分为两个文件会出错
【发布时间】:2018-10-28 07:53:10
【问题描述】:

我不熟悉使用 gradle 脚本。我有一个 build.gradle 文件,我想将其拆分为两个文件。拆分较大的 build.gradle 文件后,我得到以下两个文件。

build.gradle

buildscript {
    ext {
        springBootVersion = '1.5.12.RELEASE'
        gradleDockerVersion = '3.2.7'
    }
    repositories {
        jcenter()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("com.bmuschko:gradle-docker-plugin:${gradleDockerVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

jar {
    baseName = 'gs-spring-boot'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8
compileJava.options.encoding = 'UTF-8'

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    testCompile("junit:junit")
}
project.ext.imageName = 'myImage'
project.ext.tagName ='myTag'
project.ext.jarName = (jar.baseName + '-' + jar.version).toLowerCase()

apply from: 'dockerapp.gradle'

dockerapp.gradle

def gradleDockerVersion = '3.7.2'
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath("com.bmuschko:gradle-docker-plugin:${gradleDockerVersion}")
    }
}

apply plugin: 'com.bmuschko.docker-remote-api'

import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
import com.bmuschko.gradle.docker.tasks.image.DockerRemoveImage
import com.bmuschko.gradle.docker.tasks.image.Dockerfile

def imageName = project.ext.imageName
def tagName = project.ext.tagName
def jarName = project.ext.jarName

task createAppDockerfile(type: Dockerfile) {
    // Don't create dockerfile if file already exists
    onlyIf { !project.file('Dockerfile').exists() }
    group 'Docker'
    description 'Generate docker file for the application'
    dependsOn bootRepackage
    destFile = project.file('Dockerfile')
    String dockerProjFolder = project.projectDir.name
    from 'openjdk:8-jre-slim'
    runCommand("mkdir -p /app/springboot/${dockerProjFolder} && mkdir -p /app/springboot/${dockerProjFolder}/conf")
    addFile("./build/libs/${jarName}.jar", "/app/springboot/${dockerProjFolder}/")
    environmentVariable('CATALINA_BASE', "/app/springboot/${dockerProjFolder}")
    environmentVariable('CATALINA_HOME', "/app/springboot/${dockerProjFolder}")
    workingDir("/app/springboot/${dockerProjFolder}")
    if (System.properties.containsKey('debug')) {
        entryPoint('java', '-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=5005,suspend=n', '-jar', "/app/springboot/${dockerProjFolder}/${jarName}.jar")
    } else {
        entryPoint('java', '-jar', "/app/springboot/${dockerProjFolder}/${jarName}.jar")
    }
}

task removeAppImage(type: DockerRemoveImage) {
    group 'Docker'
    description 'Remove the docker image using force'
    force = true
    targetImageId { imageName }
    onError { exception ->
        if (exception.message.contains('No such image')) {
            println 'Docker image not found for the current project.'
        }
    }
}

task createAppImage(type: DockerBuildImage) {
    group 'Docker'
    description 'Executes bootRepackage, generates a docker file and builds image from it'
    dependsOn(createAppDockerfile, removeAppImage)
    dockerFile = createAppDockerfile.destFile
    inputDir = dockerFile.parentFile
    if (tagName)
        tag = "${tagName}"
    else if (imageName)
        tag = "${imageName}"
    else
        tag = "${jarName}"
}

如果我尝试运行命令./gradlew createAppImage,我会收到如下错误:

dockerapp.gradle 文件中的其他两个任务似乎没有问题。如果我将所有代码都放在 build.gradle 文件中,它可以正常工作而不会出现任何错误。拆分文件并执行 createAppImage 而不出错的最佳方法是什么?

【问题讨论】:

    标签: docker spring-boot gradle gradle-plugin


    【解决方案1】:

    我能够在 CDancy(插件的维护者)的帮助下解决这个问题,如下所示:

    build.gradle

    buildscript {
        ext {
            springBootVersion = '1.5.12.RELEASE'
            gradleDockerVersion = '3.2.7'
        }
        repositories {
            jcenter()
        }
        dependencies {
            classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
            classpath("com.bmuschko:gradle-docker-plugin:${gradleDockerVersion}")
        }
    }    
    
    apply plugin: 'java'
    apply plugin: 'eclipse'
    apply plugin: 'idea'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'    
    
    jar {
        baseName = 'gs-spring-boot'
        version =  '0.1.0'
    }    
    
    repositories {
        mavenCentral()
    }    
    
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    compileJava.options.encoding = 'UTF-8'    
    
    dependencies {
        compile("org.springframework.boot:spring-boot-starter-web")
        testCompile("junit:junit")
    }
    project.ext.imageName = 'myimage'
    project.ext.tagName ='mytag'
    project.ext.jarName = (jar.baseName + '-' + jar.version).toLowerCase()    
    
    apply from: 'docker.gradle'
    

    docker.gradle

    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.bmuschko:gradle-docker-plugin:3.2.7'
        }
    }
    repositories {
        jcenter()
    }
    // use fully qualified class name
    apply plugin: com.bmuschko.gradle.docker.DockerRemoteApiPlugin    
    
    // import task classes
    import com.bmuschko.gradle.docker.tasks.image.*    
    
    def imageName = project.ext.imageName
    def tagName = project.ext.tagName
    def jarName = project.ext.jarName    
    
    task createAppDockerfile(type: Dockerfile) {
        // Don't create dockerfile if file already exists
        onlyIf { !project.file('Dockerfile').exists() }
        group 'Docker'
        description 'Generate docker file for the application'
        dependsOn bootRepackage
        destFile = project.file('Dockerfile')
        String dockerProjFolder = project.projectDir.name
        from 'openjdk:8-jre-slim'
        runCommand("mkdir -p /app/springboot/${dockerProjFolder} && mkdir -p /app/springboot/${dockerProjFolder}/conf")
        addFile("./build/libs/${jarName}.jar", "/app/springboot/${dockerProjFolder}/")
        environmentVariable('CATALINA_BASE', "/app/springboot/${dockerProjFolder}")
        environmentVariable('CATALINA_HOME', "/app/springboot/${dockerProjFolder}")
        workingDir("/app/springboot/${dockerProjFolder}")
        if (System.properties.containsKey('debug')) {
            entryPoint('java', '-Xdebug', '-Xrunjdwp:server=y,transport=dt_socket,address=5005,suspend=n', '-jar', "/app/springboot/${dockerProjFolder}/${jarName}.jar")
        } else {
            entryPoint('java', '-jar', "/app/springboot/${dockerProjFolder}/${jarName}.jar")
        }
    }    
    
    task removeAppImage(type: DockerRemoveImage) {
        group 'Docker'
        description 'Remove the docker image using force'
        force = true
        targetImageId { imageName }
        onError { exception ->
            if (exception.message.contains('No such image')) {
                println 'Docker image not found for the current project.'
            } else {
                print exception
            }
        }
    }    
    
    task createAppImage(type: DockerBuildImage) {
        group 'Docker'
        description 'Executes bootRepackage, generates a docker file and builds image from it'
        dependsOn(createAppDockerfile, removeAppImage)
        dockerFile = createAppDockerfile.destFile
        inputDir = dockerFile.parentFile
        if (tagName)
            tag = "${tagName}"
        else if (imageName)
            tag = "${imageName}"
        else
            tag = "${jarName}"
    }
    

    更改基本上在我的 docker.gradle 文件中,我必须添加指向 jcenter() 的存储库部分并使用完全限定的插件类名。

    【讨论】:

      【解决方案2】:

      我想知道您为什么要在 Gradle 中使用 Docker 插件?在与维护最多的Mushko's Gradle Docker Plugin 玩了一段时间后,我不明白为什么要以不同的语法构建 plugin 样板而不是 docker 样板

      Gradle 中的容器化对程序员来说很舒服,DevOps 会说他们不像这样使用 Docker,如果你需要支持,你应该按照他们的方式去做。我在下面找到了一个简短、纯 Docker 风格且功能齐全的解决方案

      在项目结构中找到正常的Dockerfile和docker.sh shell脚本:

      在您的build.gradle 文件中:

          buildscript {
              repositories {
                  gradlePluginPortal()
              }
          }
      
          plugins {
              id 'java'
              id 'application'
          }
      
          // Entrypoint:
      
          jar {
              manifest {
                  attributes 'Main-Class': 'com.example.Test'
              }
          }
      
          mainClassName = 'com.example.Test'
      
          // Run in DOCKER-container:
      
          task runInDockerContainer {
              doLast {
                  exec {
                      workingDir '.' // Relative to project's root folder.
                      commandLine 'sh', './build/resources/main/docker.sh'
                  }
          //        exec {
          //            workingDir "."
          //            commandLine 'sh', './build/resources/main/other.sh'
          //        }
              }
          }
      

      按照正常的 Docker 文档在干净的 shell 脚本中做任何你想做的事情:

          # Everything is run relative to project's root folder:
      
          # Put everything together into build/docker folder for DOCKER-build:
          if [ -d "build/docker" ]; then rm -rf build/docker; fi;
          mkdir build/docker;
          cp build/libs/test.jar build/docker/test.jar;
          cp build/resources/main/Dockerfile build/docker/Dockerfile;
      
          # Build image from files in build/docker:
          cd build/docker || exit;
          docker build . -t test;
      
          # Run container based on image:
          echo $PWD
          docker run test;
      

      【讨论】:

      • 在您的情况下,拥有一个静态 Dockerfile 就可以了。在其他情况下,您可能希望利用 Gradle 的“dependsOn”命令动态构建 Dockerfile,其内容可能会根据项目中的其他依赖项而更改。我以这种方式设置为在单个主项目中构建 6 个 docker,并且我的 docker 仅在它们的依赖项发生更改时才构建。它非常高效,无需将 Gradle 任务与 shell 脚本混合使用。
      猜你喜欢
      • 2016-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多