如何用Gradle创建Docker镜像

陆星文
2023-12-01

https://bmuschko.github.io/gradle-docker-plugin/

1. Introduction

Gradle plugin for managing Docker images and containers using via its remote API. The heavy lifting of communicating with the Docker remote API is handled by the Docker Java library. Please refer to the library’s documentation for more information on the supported Docker’s client API and Docker server version.

 This plugin requires Gradle >= 5.2 to work properly.

1.1. Benefits

There are various benefits for using this plugin:

  1. Seamless integration with the build tool Gradle and its DSL.

  2. Handles complicated communication logic between Docker client and daemon under the covers.

  3. Simplifies the definition of complex workflows.

  4. Minimizes build script setup logic by providing sensible conventions for different use cases.

1.2. Limitations

The functionality of the plugin does not cover all possible use cases. Be aware of the following limitations:

  • A task type may not provide all possible options for the underlying Docker operation. Open an issue if you feel like it should be supported.

  • You cannot build multi-container applications via Docker Compose. The Avast Docker Compose plugin has proven to be a capable alternative.

  • Managing a Docker Swarm and/or Stack is not supported.

1.3. Further Readings

Want to learn more about using this plugin in different contexts? The following blog posts should get you started.

1.4. Provided Plugins

The binary distribution is available on the Gradle plugin portalBintray’s JCenter and Maven Central. It contains the following plugins:

Plugin IdAutomatically appliesTypeDescription

com.bmuschko.docker-remote-api

-

DockerRemoteApiPlugin

Provides custom tasks for interacting with Docker via its remote API.

com.bmuschko.docker-java-application

com.bmuschko.docker-remote-api

DockerJavaApplicationPlugin

Creates and pushes a Docker image for a Java application.

com.bmuschko.docker-spring-boot-application

com.bmuschko.docker-remote-api

DockerSpringBootApplicationPlugin

Creates and pushes a Docker image for a Spring Boot application.

Which plugin you chose in your project entirely depends on the use case you want to fulfill. Refer to the relevant portions of the user guide that describe the purpose and usage of each plugin in more detail.

1.5. Getting Started

The plugin can be applied with the buildscript syntax or the plugin DSL. Let’s say you’d want to go with the plugin that provides the plain Docker operations for managing Docker images and containers. See the Gradle user guide for more information on applying plugins.

1.5.1. Applying the Plugin Using the buildscript Syntax

Groovy

Kotlin

buildscript {
    repositories {
        gradlePluginPortal()
    }
    dependencies {
        classpath 'com.bmuschko:gradle-docker-plugin:6.4.0'
    }
}

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

1.5.2. Applying the Plugin Using the Plugin DSL

Groovy

Kotlin

plugins {
    id 'com.bmuschko.docker-remote-api' version '6.4.0'
}

1.5.3. Applying the Plugin From a Script Plugin

Applying the plugin from a script plugin requires the use of the fully-qualified class name due to a bug in Gradle core. Be aware that the plugin DSL cannot be used to apply a binary plugin from a script plugin.

 When used with the Kotlin DSL, it is recommended to move your implementation into the buildSrc project.

gradle/docker.gradle

buildscript {
    repositories {
        gradlePluginPortal()
    }
    dependencies {
        classpath 'com.bmuschko:gradle-docker-plugin:6.4.0'
    }
}

apply plugin: com.bmuschko.gradle.docker.DockerRemoteApiPlugin

build.gradle

apply from: 'gradle/docker.gradle'

2. Remote API Plugin

The plugin com.bmuschko.docker-remote-api allows for interacting with Docker via its remote API. If no additional configuration has been provided by the build script, the plugin will try to resolve and use the credentials for registry authentication available from previous login operations (usually in $HOME/.docker/config.json). You can model any workflow imaginable by creating enhanced task of the custom task provided by the plugin.

2.1. Usage

Groovy

Kotlin

plugins {
    id 'com.bmuschko.docker-remote-api' version '6.4.0'
}

// Import task types
import com.bmuschko.gradle.docker.tasks.image.*

// Use task types
task buildMyAppImage(type: DockerBuildImage) {
    inputDir = file('docker/myapp')
    images.add('test/myapp:latest')
}

The plugin automatically resolves the Docker Java library with the pre-configured version under the covers. The only configuration you will have to provide in your build script is the repository hosting the library and its transitive dependencies. One repository that hosts them all is Maven Central.

Groovy

Kotlin

repositories {
    mavenCentral()
}

2.2. Extension

The plugin defines an extension with the namespace docker. The following properties can be configured:

Property nameTypeDefault valueDescription

url

Property<String>

unix:///var/run/docker.sock (Unix), tcp://127.0.0.1:2375 (Windows)

The server URL to connect to via Docker’s remote API.

certPath

DirectoryProperty

Value of environment variable DOCKER_CERT_PATH if set

The path to certificates for communicating with Docker over SSL.

apiVersion

Property<String>

null

The remote API version. For most cases this can be left null.

Image pull or push operations against the public Docker Hub registry or a private registry may require authentication. By default, existing credentials are read from $HOME/.docker/config.json and reused for authentication purposes. You can overwrite those credentials with the help of the registryCredentials closure. The credentials provided in the extension automatically become available to all custom tasks that implement the interface RegistryCredentialsAware.

Property nameTypeDefault valueDescription

url

Property<String>

https://index.docker.io/v1/

The registry URL.

username

Property<String>

null

The registry username.

password

Property<String>

null

The registry password.

email

Property<String>

null

The registry email address.

2.2.1. Working With a TLS-enabled Docker Instance

Starting with Docker version 1.3, TLS is enabled by default. Please consult the Docker documentation "Protect the Docker daemon socket" to set up your certificate. The following example demonstrates how to configure the plugin to use those certificates. Additionally, this code snippet shows how to set the user credentials.

Groovy

Kotlin

docker {
    url = 'https://192.168.59.103:2376'
    certPath = new File(System.properties['user.home'], '.boot2docker/certs/boot2docker-vm')

    registryCredentials {
        url = 'https://index.docker.io/v1/'
        username = 'bmuschko'
        password = 'pwd'
        email = 'benjamin.muschko@gmail.com'
    }
}

2.2.2. Working With Google Cloud And Using a Key File

Groovy

Kotlin

docker {
    registryCredentials {
        url = 'https://gcr.io'
        username = '_json_key'
        password = file('keyfile.json').text
    }
}

2.2.3. Working With a Docker Instance Without TLS

The following example assumes that you disabled TLS on your Docker instance. You can do so by setting DOCKER_TLS=no in the file /var/lib/boot2docker/profile.

Groovy

Kotlin

docker {
    url = 'tcp://192.168.59.103:2375'
}

On Unix the Docker daemon listens by default on unix:///var/run/docker.sock.

On Windows the Docker daemon listens by default on npipe:./pipe/docker_engine though this is not currently supported. We instead fall back to tcp://127.0.0.1:2375.

2.3. Custom task types

2.3.1. Misc

The plugin provides the following general-purpose custom task types:

TypeDescription

DockerOperation

Passes the raw docker-java client to the onNext closure if it’s defined.

DockerInfo

Displays system-wide information.

DockerVersion

Show the docker version information.

2.3.2. Images

The plugin provides the following custom task types for managing images:

TypeDescription

Dockerfile

Creates a Dockerfile based on the provided instructions.

DockerBuildImage

Builds an image from a Dockerfile.

DockerCommitImage

Creates a new image from a container’s changes.

DockerInspectImage

Returns low-level information on the image.

DockerListImages

Lists images in registry.

DockerPullImage

Pulls an image from the registry.

DockerPushImage

Pushes an image to a registry.

DockerRemoveImage

Removes an image from the filesystem.

DockerTagImage

Tags an image in registry.

DockerSaveImage

Saves an image to file.

DockerLoadImage

Loads an image from file.

2.3.3. Containers

The plugin provides the following custom task types for managing containers:

TypeDescription

DockerCopyFileToContainer

Copies a path from the host into the container.

DockerCopyFileFromContainer

Copies a path from the container as a tar file on to the host.

DockerCreateContainer

Creates a container.

DockerInspectContainer

Returns low-level information on the container.

DockerKillContainer

Kills the container for a given id.

DockerRemoveContainer

Removes the container for a given id from the filesystem.

DockerRenameContainer

Rename a container.

DockerRestartContainer

Restarts the container for a given id.

DockerStartContainer

Starts the container for a given id.

DockerStopContainer

Stops the container for a given id.

DockerWaitContainer

Blocks until container for a given id stops.

DockerLogsContainer

Copies the container output to the Gradle process standard out/err.

DockerExecContainer

Executes a command within a running container.

DockerInspectExecContainer

Inspects task executed inside container with DockerExecContainer command.

2.3.4. Networks

The plugin provides the following custom task types for managing networks:

TypeDescription

DockerCreateNetwork

Creates a network.

DockerInspectNetwork

Returns low-level information on the network.

DockerRemoveNetwork

Removes the network.

2.3.5. Extras

The plugin provides the following additional tasks:

TypeDescription

DockerExecStopContainer

Shut down container with cmd, polling for it to enter a non-running state, and if that does not succeed in time issue stop request.

DockerLivenessContainer

Polls an arbitrary containers logs for a message indicating liveness.

DockerWaitHealthyContainer

Blocks until the container for a given id becomes healthy.

2.4. Reactive Streams

As needed, we will implement reactive methods as described in reactive-streams. We implement these here as optional closures for all tasks. Currently the only supported methods are onErroronNextonComplete. Various examples on how to use these can be found in our reactive tests.

2.4.1. Reacting to an Error

The onError closure is passed the exception that is thrown for you to handle. If you silently ignore we will not throw the exception behind the scenes. The below example is a common use-case that arises when someone wants to remove a container whether it exists or not but does not want to fail hard.

Groovy

Kotlin

task removeContainer1(type: DockerRemoveContainer) {
    targetContainerId 'container-that-does-not-exist'
    onError { exception ->
        // Ignore exception if container does not exist otherwise throw it
        if (!exception.message.contains('No such container'))
            throw exception
    }
}

2.4.2. Reacting to Data Returned by an Operation

The onNext closure is passed the next iterative response upon execution. For all other tasks we simply hand you back the object that is given to us by docker-java which is a pojo representation of the json handed back by docker. Thus, and much like the onError closure, all delegation is now in your control. Any properties/values expected to be set will not be done unless you do them.

Iterative tasks are things like DockerBuildImageDockerLogsContainerDockerListImages. These tasks have output which can be iterated over. The example below demonstrates how we iterate over each log message passing that to the closure for the user to work on.

Groovy

Kotlin

task logContainer(type: DockerLogsContainer) {
    targetContainerId 'container-that-does-exist'
    follow = true
    tailAll = true
    onNext { message ->
        // Each log message from the container will be passed as it's made available
        logger.quiet message.toString()
    }
}

2.4.3. Reacting to the Completion of an Operation

The onComplete closure is not passed anything upon execution. It works in the same fashion that doLast does but is instead part of this task and thus executes before doLast does. This closure executes only upon success. The below example demonstrates how this works.

Groovy

Kotlin

task removeContainer2(type: DockerRemoveContainer) {
    targetContainerId 'container-that-does-exist'
    onComplete {
        println 'Executes first'
    }
    doLast {
        println 'Executes second'
    }
}

2.5. Examples

The following usage examples demonstrate code for common use cases. More scenarios can be found in the functional tests.

2.5.1. Modifying Instructions of a Dockerfile Task

Sometimes do you do not have any control over the creation of a Dockerfile task. For example the Docker Java Application Plugin already adds a Dockerfile task with a set of sensible instructions. You can still modify those instructions if needed. Let’s say you are dealing with the following Dockerfile definition.

Groovy

Kotlin

tasks.create('createDockerfile', Dockerfile) {
    from('openjdk:jre-alpine')
    copyFile('my-app-1.0.jar', '/app/my-app-1.0.jar')
    entryPoint('java')
    defaultCommand('-jar', '/app/my-app-1.0.jar')
    exposePort(8080)
}

Now, you may prefer a different base image than the one added by default. The listing below demonstrates how to find it the FROM instruction and replace it with a different one.

Groovy

Kotlin

createDockerfile {
    List<Instruction> originalInstructions = new ArrayList<Instruction>(instructions.get())
    int fromInstructionIndex = originalInstructions
            .findIndexOf { it.keyword == FromInstruction.KEYWORD }
    originalInstructions.remove(fromInstructionIndex)
    FromInstruction baseImage = new FromInstruction(new From('openjdk:8-alpine'))
    originalInstructions.add(0, baseImage)
    instructions.set(originalInstructions)
}

You can also add new instructions at a specific position in the existing list of instructions. For example you may want to add a HEALTHCHECK to the end of the list.

Groovy

Kotlin

createDockerfile {
    instruction 'HEALTHCHECK CMD wget --quiet --tries=1 --spider http://localhost:8080/actuator/health || exit 1'
}

2.5.2. Creating a Dockerfile And Building an Image

A Dockerfile can be created by the Dockerfile custom tasks. The Dockerfile instructions need to be declare in the correct order.

Groovy

Kotlin

plugins {
    id 'com.bmuschko.docker-remote-api' version '6.4.0'
}

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

task createDockerfile(type: Dockerfile) {
    from 'ubuntu:12.04'
    label(['maintainer': 'Benjamin Muschko "benjamin.muschko@gmail.com"'])
}

task buildImage(type: DockerBuildImage) {
    dependsOn createDockerfile
    images.add('bmuschko/myimage:latest')
}

2.5.3. Executing Functional Tests Against a Running Container

The following example code demonstrates how to build a Docker image from a Dockerfile, starts up a container for this image and exercises functional tests against the running container. At the end of this operation, the container is stopped.

Groovy

Kotlin

plugins {
    id 'com.bmuschko.docker-remote-api' version '6.4.0'
}

import com.bmuschko.gradle.docker.tasks.container.*
import com.bmuschko.gradle.docker.tasks.image.*

task buildMyAppImage(type: DockerBuildImage) {
    inputDir = file('docker/myapp')
    images.add('test/myapp:latest')
}

task createMyAppContainer(type: DockerCreateContainer) {
    dependsOn buildMyAppImage
    targetImageId buildMyAppImage.getImageId()
    hostConfig.portBindings = ['8080:8080']
    hostConfig.autoRemove = true
}

task startMyAppContainer(type: DockerStartContainer) {
    dependsOn createMyAppContainer
    targetContainerId createMyAppContainer.getContainerId()
}

task stopMyAppContainer(type: DockerStopContainer) {
    targetContainerId createMyAppContainer.getContainerId()
}

task functionalTestMyApp(type: Test) {
    dependsOn startMyAppContainer
    finalizedBy stopMyAppContainer
}

2.5.4. Linking With Other Containers

In many situations your container does not start without dependencies like database. In that case you may wish using traditional linking:

Groovy

Kotlin

plugins {
    id 'com.bmuschko.docker-remote-api' version '6.4.0'
}

import com.bmuschko.gradle.docker.tasks.container.*
import com.bmuschko.gradle.docker.tasks.image.*

task buildMyAppImage(type: DockerBuildImage) {
    inputDir = file('docker/myapp')
    images.add('test/myapp')
}

task createDBContainer(type: DockerCreateContainer) {
    targetImageId 'postgres:latest'
    containerName = 'docker_auto'
    hostConfig.autoRemove = true
}

task createMyAppContainer(type: DockerCreateContainer) {
    dependsOn buildMyAppImage, createDBContainer
    targetImageId buildMyAppImage.getImageId()
    hostConfig.portBindings = ['8080:8080']
    hostConfig.autoRemove = true
    hostConfig.links = ["docker_auto:database"]

    // If you use Systemd in containers you should also add lines. #320
    hostConfig.binds = ['/sys/fs/cgroup': '/sys/fs/cgroup']
    tty = true
}

task startMyAppContainer(type: DockerStartContainer) {
    dependsOn createMyAppContainer
    targetContainerId createMyAppContainer.getContainerId()
}

task stopMyAppContainer(type: DockerStopContainer) {
    targetContainerId createMyAppContainer.getContainerId()
}

task functionalTestMyApp(type: Test) {
    dependsOn startMyAppContainer
    finalizedBy stopMyAppContainer
}

2.5.5. Implementing Custom Docker Client Handling

The plugin provides an opinionated set of custom tasks for the most common Docker operations. Sometime the situation may arise that you want to have full control over what you want to call on the Docker client. To do so you can implement your own custom task that extends from AbstractDockerRemoteApiTask. The following example shows how to implement such a custom task:

Groovy

Kotlin

class DockerImageIdForName extends AbstractDockerRemoteApiTask {
    @Input
    final Property<String> filteredImageName = project.objects.property(String)

    @Internal
    final Property<String> imageId = project.objects.property(String)

    DockerImageIdForName() {
        onNext({ image ->
            imageId.set(image.id)
        })
    }

    @Override
    void runRemoteCommand() {
        def images = dockerClient.listImagesCmd()
            .withImageNameFilter(filteredImageName.get())
            .exec()

        for(image in images) {
            nextHandler.execute(image)
        }
    }
}

To use the custom task, simply create a task by type.

Groovy

Kotlin

task imageIdForName(type: DockerImageIdForName) {
    filteredImageName = 'alpine:3.4'
}

task printImageId {
    dependsOn imageIdForName
    doLast {
        logger.quiet "Resolved image ID ${imageIdForName.imageId.get()} for name ${imageIdForName.filteredImageName.get()}"
    }
}

3. Java Application Plugin

The plugin com.bmuschko.docker-java-application is a highly opinionated plugin for projects applying the Java plugin. Under the hood the plugin preconfigures tasks for creating and pushing Docker images for your Java application. The default configuration is tweakable via an exposed extension.

3.1. Usage

Groovy

Kotlin

plugins {
    id 'java'
    id 'com.bmuschko.docker-java-application' version '6.4.0'
}

3.2. Extension

The plugin defines an extension with the namespace javaApplication as a child of the docker namespace. By default, the main class will be configured automatically by looking for a class with a public static void main(String[]) method available in the classpath of the main source set.

The following properties can be configured:

Property nameTypeDefault valueDescription

baseImage

Property<String>

openjdk:jre-alpine

The Docker base image used for Java application.

maintainer

Property<String>

Value of system property user.name

The maintainer of the image.

ports

ListProperty<Integer>

[8080]

The Docker image exposed ports.

images

SetProperty<String>

[<project.group>/<applicationName>:<project.version>]

The images used for the build and push operation.

jvmArgs

ListProperty<String>

[]

The JVM arguments passed to the java command.

mainClassName

Property<String>

A unique main class name discovered by scanning the classpath

The main class name to use for starting the application. Setting an explicit value for this option is useful if your source code contains multiple main class files.

Groovy

Kotlin

docker {
    javaApplication {
        baseImage = 'dockerfile/java:openjdk-7-jre'
        maintainer = 'Benjamin Muschko "benjamin.muschko@gmail.com"'
        ports = [9090, 5701]
        images = ['jettyapp:1.115', 'jettyapp:latest']
        jvmArgs = ['-Xms256m', '-Xmx2048m']
    }
}

3.3. Tasks

The plugin provides a set of tasks for your project and preconfigures them with sensible defaults.

Task nameDepends OnTypeDescription

dockerSyncBuildContext

classes

Sync

Copies the application files to a temporary directory for image creation.

dockerCreateDockerfile

dockerSyncBuildContext

Dockerfile

Creates the Docker image for the Java application.

dockerBuildImage

dockerCreateDockerfile

DockerBuildImage

Builds the Docker image for the Java application.

dockerPushImage

dockerBuildImage

DockerPushImage

Pushes created Docker image to the repository.

3.4. Examples

The following usage examples demonstrate code for common use cases. More scenarios can be found in the functional tests.

3.4.1. Using the Plugin for an Application Run on Jetty

Groovy

Kotlin

plugins {
    id 'java'
    id 'com.bmuschko.docker-java-application' version '6.4.0'
}

version = '1.0'
sourceCompatibility = 1.7

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.eclipse.jetty.aggregate:jetty-all:9.2.5.v20141112'
}

docker {
    javaApplication {
        maintainer = 'Jon Doe "jon.doe@gmail.com"'
    }
}

3.4.2. Additional Instructions in Dockerfile

You can add additional instructions to the dockerfile using dockerDistTar and Dockerfile task DSL:

Groovy

Kotlin

dockerCreateDockerfile {
    instruction 'RUN ls -la'
    environmentVariable 'JAVA_OPTS', '-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap'
}

Or you can use form

Groovy

Kotlin

dockerCreateDockerfile.instructionsFromTemplate file('Dockerfile.tmpl')

4. Spring Boot Application Plugin

The plugin com.bmuschko.docker-spring-boot-application is a highly opinionated plugin for projects applying the Spring Boot plugin. Under the hood the plugin preconfigures tasks for creating and pushing Docker images for your Spring Boot application. The default configuration is tweakable via an exposed extension. The plugin reacts to either the java or war plugin.

 The plugin only supports projects that use a 2.x version of the Spring Boot plugin.

4.1. Usage

Groovy

Kotlin

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.0.3.RELEASE'
    id 'com.bmuschko.docker-spring-boot-application' version '6.4.0'
}

4.2. Extension

The plugin defines an extension with the namespace springBootApplication as a child of the docker namespace. By default, the main class will be configured automatically by looking for a class with a public static void main(String[]) method available in the classpath of the main source set. The main class needs to use the org.springframework.boot.autoconfigure.SpringBootApplication annotation to be discoverable.

The following properties can be configured:

Property nameTypeDefault valueDescription

baseImage

Property<String>

openjdk:jre-alpine

The Docker base image used for the Spring Boot application.

maintainer

Property<String>

Value of system property user.name

The maintainer of the image.

ports

ListProperty<Integer>

[8080]

The Docker image exposed ports.

images

SetProperty<String>

[<project.group>/<applicationName>:<project.version>]

The images used for the build and push operation.

jvmArgs

ListProperty<String>

[]

The JVM arguments passed to the java command.

mainClassName

Property<String>

A unique main class name discovered by scanning the classpath

The main class name to use for starting the application. Setting an explicit value for this option is useful if your source code contains multiple main class files.

Groovy

Kotlin

docker {
    springBootApplication {
        baseImage = 'openjdk:8-alpine'
        ports = [9090, 8080]
        images = ['awesome-spring-boot:1.115', 'awesome-spring-boot:latest']
        jvmArgs = ['-Dspring.profiles.active=production', '-Xmx2048m']
    }
}

4.3. Tasks

The plugin provides a set of tasks for your project and preconfigures them with sensible defaults.

Task nameDepends OnTypeDescription

dockerSyncBuildContext

classes

Sync

Copies the application files to a temporary directory for image creation.

dockerCreateDockerfile

dockerSyncBuildContext

Dockerfile

Creates the Docker image for the Spring Boot application.

dockerBuildImage

dockerCreateDockerfile

DockerBuildImage

Builds the Docker image for the Spring Boot application.

dockerPushImage

dockerBuildImage

DockerPushImage

Pushes created Docker image to the repository.

4.4. Examples

The following usage examples demonstrate code for common use cases. More scenarios can be found in the functional tests.

4.4.1. Using the Plugin For an Application Run on Tomcat

The Spring Boot archive can be created as executable JAR or WAR file. If you are target environment is a Servlet Container or Application Server, the WAR file is likely the better option. To generate a WAR file, simply apply the war plugin and declare the appropriate container-related dependencies to run the application locally.

Groovy

Kotlin

plugins {
    id 'war'
    id 'org.springframework.boot' version '2.0.3.RELEASE'
    id 'io.spring.dependency-management' version '1.0.5.RELEASE'
    id 'com.bmuschko.docker-spring-boot-application' version '6.4.0'
}

version = '1.0'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

repositories {
    jcenter()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    providedRuntime 'org.apache.tomcat.embed:tomcat-embed-jasper'
}

docker {
    springBootApplication {
        baseImage = 'openjdk:8-alpine'
    }
}

4.4.2. Providing Container Build-Time and Runtime Parameters

It’s common practice to provide JVM parameters to a Spring Boot application running in a container. For example, you might want to provide memory parameters or set a specific Spring profile. There’s a two ways to achieve this. Each of them serve different use cases.

You may want to provide JVM parameters when you build the image with a Dockerfile. That’s likely the case if you don’t want to change the parameters later when running the image in a container. You can provide a list of JVM parameters that should be baked into image with the extension property jvmArgs.

Hard-coding a JVM parameter may not be the right solution to your problem. There are situations when you want to provide runtime behavior when starting the container. A typical example is a Spring profile that needs to be enabled depending on the environment you want to run.

If you are running the image with Docker, then you can just provide pre-built environment variables known to Spring Boot. Below, we are running an application with the prod profile.

$ docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t my-spring-boot-app:1.2.3

You can achieve the same behavior in Kubernetes by defining an environment variable in your Pod or Deployment spec. The example below demonstrates the use of a Deployment.

deployment.yaml

kind: Deployment
apiVersion: apps/v1
metadata:
  name: my-spring-boot-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-spring-boot-app
  template:
    metadata:
      labels:
        app: my-spring-boot-app
    spec:
      containers:
        - name: my-spring-boot-app
          image: my-spring-boot-app:1.2.3
          env:
          - name: SPRING_PROFILES_ACTIVE
            value: prod

5. About This Project

5.1. Maintainers

5.2. Contributing

Over the years, the plugin has tremendously grown in popularity. Contributions from the community are very welcome. Have a look at the contribution guidelines to get started.

5.3. Development

5.3.1. Executing the Plugin’s Test Suite With Custom Configuration

It is required to install and run Docker Community Edition (CE) on the machine running tests. Please refer to the installation manual for more information. The default setup can be configured with the help of the properties shown in the table below:

DescriptionSystem/Project PropertyEnvironment VariableDefault Value

Docker server URL

dockerServerUrl

DOCKER_HOST

unix:///var/run/docker.sock

Docker cert path

dockerCertPath

DOCKER_CERT_PATH

null

Docker private registry URL

dockerPrivateRegistryUrl

DOCKER_REGISTRY_HOST

http://localhost:5000

The following usage examples demonstrates running functional tests against the a Docker instance:

$ ./gradlew functionalTest

OR

$ ./gradlew functionalTest -PdockerServerUrl=unix:///var/run/docker.sock

OR

$ ./gradlew functionalTest -DdockerServerUrl=unix:///var/run/docker.sock

OR

$ export DOCKER_HOST=unix:///var/run/docker.sock && ./gradlew functionalTest

OR

$ ./gradlew functionalTest -PdockerServerUrl=http://192.168.59.103:2376

5.4. Release Process

This section describes the release process designed and implemented for this project. Its main purpose is to explain to developers and maintainers how to prepare and release a new version of the binaries and the documentation.

5.4.1. Tools

The release process uses some external libraries and services described in detail below.

gradle-git

The gradle-git plugin is used to automatically determine the project version. org.ajoberstar.release-opinion is applied in the main build.gradle and configured in ReleasePlugin.kt. Please refer to the plugin documentation for more details.

gradle-git-publish

The gradle-git-publish Gradle plugin is used to publish the documentation to gh-pages branch. It is applied and configured in the DocumentationPlugin.kt file.

Travis CI

Travis CI service is used as our current CI/CD server. Build and deploy jobs are configured in .travis.yml file. Please refer its documentation for more details.

Bintray’s JCenter

Bintray’s JCenter service is used to publish plugin versions. The Bintray plugin uploads artifacts to a remote repository. The plugin configuration can be found in the PublishingPlugin.kt file.

5.4.2. Workflow

The release process is automated to some extent. The following steps describe the workflow.

  1. Developer updates RELEASE_NOTES.md with new planned version.

  2. Developer commits all changes in local working copy.

  3. Developer triggers new version release using the following command: ./gradlew release -Prelease.stage=final -Prelease.scope=[SCOPE] where [SCOPE] can be one of majorminor or patch, and determines which part of the version string <major>.<minor>.<patch> will be incremented.

  4. Gradle executes a build on developer’s machine which calculates new version string, creates new tag with it and pushes to the origin.

  5. When Gradle build is finished, developer’s work is done and the rest of the release process is automated.

  6. After push to the origin, Travis detects new tag and triggers a build.

  7. Travis is instructed to execute release stage when on Git tag.

  8. In this stage Gradle script assembles plugin binaries (with new version) and uploads them to Bintray (credentials are stored as secure variables in Travis). Furthermore, the API docs and the user guide are published to gh-pages branch (the access token is stored as secure variable).

5.4.3. Useful Links

 

具体可以参考:https://bmuschko.github.io/gradle-docker-plugin/

 

 类似资料: