Using Docker from Java Gradle

Not limited to this time, would you like to ride on the shoulders of giants and make the package convenient? Last time I will start from the place where I made the package. Again, there is Source Code. Please read from time to time (README has a rough tone, but please forgive me).

Introductory plugin

This time, we will use Palantir Technologies (data analysis industry) in the United States. These are docker plugins. "Tachi" is because docker, docker-run, and docker-compose each have their own plugins. https://github.com/palantir/gradle-docker I wonder if compose is good this time ... For the time being, we will handle everything from gradle to container startup.

Each procedure

1. Create Dockerfile

Well, it won't work without this ... This is what I made this time.

Dockerfile


FROM amazonlinux:latest

RUN yum update -y &&\
    yum upgrade -y &&\
    yum install java-11-amazon-corretto-headless -y

COPY ./build/libs/gradle-docker.jar /tmp/app.jar
ENTRYPOINT ["java", "-jar", "/tmp/app.jar"]

I'm assuming Amazon ECS / Fargate / EKS as a cloud environment, so it's amazon linux (thinking abandoned). If image size is important, ubuntu or alpine is more likely. There's nothing you can't do to rush corretto into alpine ... I'm grateful that Java is 11 and LTS can be used for free. Anyway, first comment out COPY and ENTRYPOINT to see if it works.

2. Write docker startup in the build script

This is a difficult place. First, fill in the plugin.

build.gradle


plugins {
  id 'java'
  id 'application'
  id 'idea'
  id 'eclipse'
  id 'com.palantir.docker' version '0.25.0'
  id 'com.palantir.docker-run' version '0.25.0'
}

Then, we will add various options to the task: docker that the plugin has. The download of copySpec is difficult to understand, so I will explain it later.

build.gradle


docker {
  // name:This will be the name of the built container image.
  //The right side separated by a colon is recognized as a tag.
  name "${project.name}:${project.version}"
  //Needless to say, this is a Dockerfile.
  //The path is.\It works with or without it.
  dockerfile file('Dockerfile')
  //Use Gradle's copy specs to bring the built materials to the plugin destination.
  copySpec.from('build/libs').into('build/libs')
  //cache use of docker build off
  noCache true
  //Dependency definition: After gradle docker, gradle build will run before that
  dependsOn tasks.build
}

Now, if you say "gradle docker" on the basic command line, it should run.

Well, since it's a big deal, do you want to go to start the container? The plugin is already included, so all you have to do is add a task option. Since the container startup options are different for each person, Please read the Documentation carefully.

build.gradle


dockerRun {
  //The container name.
  name project.name
  //Image to boot(The one I made with the docker task)
  image "${project.name}:${project.version}"
  //Start the container daemon? : Docker run"-d" <-this guy
  daemonize false  //No, I manifest
  //Are you a tuna?(stop then auto terminate)
  clean true //It ’s a tuna.
}

And now, if you hit the following command, it should be for the time being.

$ ./gradlew docker
$ ./gradlew dockerRun
Hello World.

However, there is a little more work to be done.

3. Make fat Jar

Currently there is no library so it works fine, When I poke in the framework library, it fails with classNotFound. The only way to get rid of it is to put the library jar in the jar file to build (but not easy). This is also easy if you use a plugin. ShadowJar, let's use this this time. First add the plugin,

build.gradle


plugins {
  id 'java'
  id 'application'
  id 'idea'
  id 'eclipse'
  id 'com.palantir.docker' version '0.25.0'
  id 'com.palantir.docker-run' version '0.25.0'
  id 'com.github.johnrengelman.shadow' version '6.1.0' // <-this guy
}

Then add the task options. It says finalized By inside. I didn't tell you this when I added the docker task, It is an explicit way to move on to the next task after this task is completed properly. In other words, in this case, you want to do the docker task after creating the jar with the shadowJar task. By adding dependsOn for subsequent tasks, it will certainly be executed with shadowJar-> docker. However, there is no guarantee that shadowJar will complete before the docker task runs. To be honest, I'm a little stuck ... task-dependent mess ...

build.gradle


shadowJar {
  //Since it does not refer to the jar task, specify the archive file here as well
  archiveFileName = "${project.name}.jar"
  //Dependencies
  finalizedBy tasks.docker
}

And you should have been able to create and start the image properly with the above-mentioned gradle docker / dockerRun command.

Internal movement

As for the docker plugin, the key is a file that plunges into the image. The plugin stores materials (including Dockerfile) under / build / docker, I'm using it for image builds. So you have to do that in the docker task options. The plugin uses Gradle's "copySpec" API. So from /build/libs/* to /build/docker/build/libs/* It means that you are copying files in this way. So, the Dockerfile that was also copied under build / docker Find ./build/libs/your.jar from that location and COPY it into the image. By the way, you can do the same by combining the task docker options file and copySpec.

build.gradle


docker {
  name "${project.name}:${project.version}"
  dockerfile file('Dockerfile')
  files shadowJar.archiveFile.get()
  copySpec.into('build/libs')
  noCache true
  dependsOn tasks.shadowJar
}

By pre-populating the files option, it will also be listed in copySpec. You can use this to dig into the image even if you have another environment file that you don't pack in a jar.

If you use it for development

It may be a sermon to Buddha, We recommend rewriting the Dockerfile for development. Even though I build an image with gradle docker every time, I drop jdk and insco it, so it will wither. Create an image that even created a java environment, After that, it is overwhelmingly cost effective to comment out that part and direct it to the image that made the FROM.

Dasoku

However, this plug-in group is awesome, there are many things that can be done. You can do various things such as using image push and compose. I always feel that I am an engineer because there are such things and I can use them.

By the way, to change the story, "riding on the shoulders of giants" is not a metaphor, it's really a giant. It's about science fiction. Turian is kind.


Also, since it is a little troublesome, I will also make docker rmi with a gradle task. One thing I expect from plugins is that there's nothing I can't do.

Recommended Posts

Using Docker from Java Gradle
Launch Gradle from Ant
Using Docker from Java Gradle
Gradle
Sample code using Minio from Java
Data processing using stream API from Java 8
Using JavaScript from Java in Rhino 2021 version
Connect from Java to MySQL using Eclipse
Call Java methods from Nim using jnim
Access Forec.com from Java using Axis2 Enterprise WSDL
Make SpringBoot1.5 + Gradle4.4 + Java8 + Docker environment compatible with Java11
Build Java x Spring x VSCode x Gradle on Docker (1)
Try accessing the dataset from Java using JZOS
Using Gradle with VS Code, build Java → run
Ssh connect using SSHJ from a Java 6 app
Sorting using java comparator
Call Java from JRuby
Changes from Java 8 to Java 11
Sum from Java_1 to 100
Eval Java source from Java
First gradle build (Java)
Scraping practice using Java ②
Access API.AI from Java
Scraping practice using Java ①
About Java 10 Docker support
Launch Gradle from Ant
Launch Docker from Java to convert Office documents to PDF
Output the maximum value from the array using Java standard output
Build VS Code + WSL + Java + Gradle environment from scratch
[Java] Text extraction from PowerPoint (ppt) using Apache POI
Using the database (SQL Server 2014) from a Java program 2018/01/04
[Note] Create a java environment from scratch with docker
Try to build a Java development environment using Docker
Monitor Azure AppService log stream from Terminal (using Docker)
Java multi-project creation with Gradle
Migration from Cobol to JAVA
Spring + Gradle + Java Quick Start
[Gradle] About Java plug-in tasks
Try scraping using java [Notes]
Try using Cocoa from Ruby
Java starting from beginner, override
Creating ElasticSearch index from Java
New features from Java7 to Java8
Oracle Java 8 on Docker Ubuntu
Migrating from vargrant to docker
Gradle settings for using JUnit 5
Extract files from Docker Image
Connect from Java to PostgreSQL
Java, instance starting from beginner
Using Mapper with Java (Spring)
Java starting from beginner, inheritance
Java life starting from scratch
Try Hello World using plain Java on a Docker container
From Ineffective Java to Effective Java
JavaScript as seen from Java
Make a rhombus using Java
multi-project docker build using jib
People using docker Try using docker-compose
Bubble sort using ArrayList (JAVA)
Using PlantUml with Honkit [Docker]
Execute non-Java instructions from Java
Sample of using Salesforce's Bulk API from Java client with PK-chunking
Try passing values from Java Servlet to iPhone app using JSON