Com.palantir.docker: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 188: Line 188:
==dockerfile==
==dockerfile==


The dockerfile to use for building the image. It defaults to project.file('Dockerfile'), which implies that the corresponding Dockerfile file exists in the project root, alongside build.gradle. It must be a file object.
The dockerfile to use for building the image. It defaults to project.file('Dockerfile'), which implies that the corresponding Dockerfile file exists in the project root, alongside [[build.gradle]]. It must be a file object.


<syntaxhighlight lang='groovy'>
<syntaxhighlight lang='groovy'>

Revision as of 22:01, 21 October 2020

External

Internal

Overview

Latest Version

https://plugins.gradle.org/m2/com/palantir/docker/com.palantir.docker.gradle.plugin/

build.gradle

Using plugin DSL:

plugins {
  id "com.palantir.docker" version "0.25.0"
}

Alternatively, use legacy format common section:

buildscript {

    ext {

        ...
        dockerGradleVersion = '0.21.0'
    }

    repositories {

        mavenCentral()

        maven {
            
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        ...
        classpath("gradle.plugin.com.palantir.gradle.docker:gradle-docker:${dockerGradleVersion}")
    }
}

ext {
    
    dockerNamespace = "com.example/playground"
}

...

apply plugin: 'com.palantir.docker'

...

Spring Boot Application Container

The docker plugin configuration that creates a SpringBoot application container. This configuration requires the common section, above.

docker {
    
  dependsOn build as Task

  // bootJar.baseName resolves to the artifact name, without version and extension information
  name "${dockerNamespace}/${bootJar.baseName}"

  dockerfile file('Dockerfile')

  // bootJar.archivePath resolves to the absolute path of the artifact file
  files bootJar.archivePath

  // bootJar.archiveName resolves to the artifact name, including version and extension
  buildArgs(['JAR_FILE': "${bootJar.archiveName}"])
}

The corresponding Dockerfile:

FROM openjdk:8-jdk-alpine
ARG JAR_FILE
COPY ${JAR_FILE} /app.jar
RUN apk --no-cache add curl bash bind-tools
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

Application Plugin Distribution Container

This is the docker plugin configuration that builds a container based on an application distribution built by the Application plugin. This configuration requires the common section, above.

docker {

    dependsOn distZip as Task

    //
    // define the distribution file
    //
    String distributionBaseName = ((DistributionContainer)project.extensions.getByName("distributions")).getByName("main").baseName;
    File distributionZip = new File(new File(project.buildDir, "distributions"), distributionBaseName + ".zip")

    name "${dockerNamespace}/${distributionBaseName}:latest"

    dockerfile file('Dockerfile')

    files distributionZip

    buildArgs(['DISTRIBUTION_ZIP': distributionZip.name])
}

The corresponding Dockerfile:

FROM openjdk:8-jdk-alpine
ARG DISTRIBUTION_ZIP
COPY ${DISTRIBUTION_ZIP} .
RUN apk --no-cache add curl bash bind-tools unzip; unzip ${DISTRIBUTION_ZIP}; rm ${DISTRIBUTION_ZIP}
ENTRYPOINT ["/oa2aws/bin/oa2aws"]

Configuration

The plugin configuration is applied in a docker {} script block. The following parameters are available:

name

The container name. Includes the namespace and may include a tag. Example:

docker {
  ...
  name com.example/my-container:latest
  ...
}

name the name to use for this container, may include a tag. This syntax is convenient if only one tag is applied. If more than one tags are used, there is an alternative syntax that uses the "tag" attribute. See tag below.

tag

Specifies one or more tags to be applied then when the container image is placed in the repository. The syntax of the tag configuration parameter is

...
tag <task-name> <tag>
...

where the task-name is used to create a new tagging task, named "dockerPush-task-name"

The following configuration:

docker {
  ...
  name com.example/my-container
  
  tag "-${version}", "${ecrRepositoryUri}:${version}"
  tag "-latest", "${ecrRepositoryUri}:latest"
  ...
}

activated with:

gradle dockerTagsPush

will tag twice:

> Task :dockerPush-1.1-SNAPSHOT
The push refers to repository [777777777777.dkr.ecr.us-west-2.amazonaws.com/oa2aws]
b5399c55eada: Preparing
...
1.1-SNAPSHOT: digest: sha256:ad78e5752e1a819b6360bfb3ba5bfa4eb38fa8d88f6fb970d1b0efd483c6ab30 size: 1371

> Task :dockerPush-latest
The push refers to repository [673499572719.dkr.ecr.us-west-2.amazonaws.com/oa2aws]
b5399c55eada: Preparing
...
latest: digest: sha256: ad78e5752e1a819b6360bfb3ba5bfa4eb38fa8d88f6fb970d1b0efd483c6ab30 size: 1371

dockerfile

The dockerfile to use for building the image. It defaults to project.file('Dockerfile'), which implies that the corresponding Dockerfile file exists in the project root, alongside build.gradle. It must be a file object.

docker {
  ...
  dockerfile file('Dockerfile')
  ...
}

If Dockerfile is maintain in src/main/docker/Dockerfile:

docker {
  ...
  dockerfile file('src/main/docker/Dockerfile')
  ...
}

files

An argument list of files to be included in the Docker build context, evaluated per Project#files

docker {
  ...
  files bootJar.archivePath, './build/themyscira-openapi-with-aws-extensions.json'
  ...
}

buildArgs

An argument map of string-to-string which will set --build-arg arguments to the docker build command and pass Docker build-time variables. It defaults to empty, which results in no --build-arg parameters.

Single argument:

docker {
  ...
  buildArgs(['DISTRIBUTION_FILE': distribution.name])
}

Multiple arguments:

docker {
  ...
  buildArgs(['DISTRIBUTION_FILE': distribution.name, 'DISTRIBUTION_IMAGE_DIR': distributionImageDir])
}

The arguments passed as such can then be used in the Dockerfile as follows:

...
ARG DISTRIBUTION_FILE
ARG DISTRIBUTION_IMAGE_DIR
COPY ${DISTRIBUTION_FILE} ${DISTRIBUTION_IMAGE_DIR}/${DISTRIBUTION_FILE}
...

More details about Docker build-time variables:

Docker Build-Time Variables

Idiosyncrasies

com.palantir.docker and Distribution Plugin

The output of dockerfileZip task is called project-name.zip by default. When the plugin is used together with the distribution plugin, they break each other. The distribution plugin will output its zip file with the same name, which gets overwritten by the dockerfileZip. Workaround is the following build.gradle snippet:

dockerfileZip {
  baseName 'dockerfile'
}

RUN Executables Failure is Not Reported

Under some non-elucidated circumstances, the Dockerfile RUN commands silently fail, but the build process is not aborted, leading to incomplete or invalid images. For example, using $(basename ...) failed silently.

Operations

Build the Image and Place it in the Local Registry

gradle clean docker

The command will build the container image and place into the local registry as "com.example/playground/myartifact" with the "latest" tag.

"Normalized" build Task

If the docker tasks belongs to a dedicated docker sub-project, that does not have a "build" task, the project can be "normalized" with a build task as follows:

task build {
    dependsOn getTasksByName("docker", false).asList().get(0)
}

Declare docker Tasks' Dependencies on other Tasks

In most cases it is necessary to first build the artifacts that will be package in the container image. The task dependency can be expressed as follows:

docker {
  ...
  dependsOn build
  ...
}

For more details, see:

Task Execution Order

Push to External Repository

gradle docker dockerPush

Avoid Unzipping as a Container Build Operation

When packaging a ZIP distribution, one of the steps is to unzip the distribution file. This is unnecessary, as Gradle build area already contains the unzipped contents. Come up with the recipe to use that and avoid RUN unzip ... in the Dockerfile. Some ideas are available here: https://github.com/palantir/gradle-docker.

Execution Internals

The build context is a local directory similar to /var/lib/docker/tmp/docker-builder036476946.