Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running simple Java Gradle app in Docker

I have a simple Java server app with a Gradle build. It works perfectly with gradle run on my host machine. However, I want to build this in a docker image and run as a docker container.

I'm using docker-machine (version 0.13.0):

docker-machine create --driver virtualbox --virtualbox-memory 6000 default
docker-machine start
eval $(docker-machine env default)

I have the following Dockerfile image build script in ./serverapp/Dockerfile:

FROM gradle:4.3-jdk-alpine
ADD . /code
WORKDIR /code
CMD ["gradle", "--stacktrace", "run"]

I can build perfectly:

➜  docker build -t my-server-app .
Sending build context to Docker daemon  310.3kB
Step 1/4 : FROM gradle:4.3-jdk-alpine
 ---> b803ec92baec
Step 2/4 : ADD . /code
 ---> Using cache
 ---> f458b0be79dc
Step 3/4 : WORKDIR /code
 ---> Using cache
 ---> d98d04eda627
Step 4/4 : CMD ["gradle", "--stacktrace", "run"]
 ---> Using cache
 ---> 869262257870
Successfully built 869262257870
Successfully tagged my-server-app:latest

When I try to run this image:

➜  docker run --rm my-server-app

FAILURE: Build failed with an exception.

* What went wrong:
Could not create service of type ScriptPluginFactory using BuildScopeServices.createScriptPluginFactory().
> Could not create service of type CrossBuildFileHashCache using BuildSessionScopeServices.createCrossBuildFileHashCache().

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.internal.service.ServiceCreationException: Could not create service of type ScriptPluginFactory using BuildScopeServices.createScriptPluginFactory().
    at org.gradle.internal.service.DefaultServiceRegistry$FactoryMethodService.invokeMethod(DefaultServiceRegistry.java:797)

  <snip>
    ... 60 more
Caused by: org.gradle.api.UncheckedIOException: Failed to create parent directory '/code/.gradle/4.3' when creating directory '/code/.gradle/4.3/fileHashes'
    at org.gradle.util.GFileUtils.mkdirs(GFileUtils.java:271)
    at org.gradle.cache.internal.DefaultPersistentDirectoryStore.open(DefaultPersistentDirectoryStore.java:56)

Why would it have trouble creating that directory?

This should be a very easy task, can anyone tell me how they get this simple scenario working?

FYI, running current versions of everything. I'm using Gradle 4.3.1 on my host, and the official Gradle 4.3 base image from docker hub, I'm using the current version of JDK 8 on my host and the current version of docker, docker-machine, and docker-compose as well.

like image 790
clay Avatar asked Nov 16 '17 23:11

clay


2 Answers

The fix was to specify --chown=gradle permissions on the /code directory in the Dockerfile. Many Docker images are designed to run as root, the base Gradle image runs as user gradle.

FROM gradle:4.3-jdk-alpine
ADD --chown=gradle . /code
WORKDIR /code
CMD ["gradle", "--stacktrace", "run"]

Ethan Davis suggested using /home/gradle rather than code. That would probably work as well, but I didn't think of that.

The docker image maintainer should have a simple getting started type reference example that shows the recommended way to get basic usage.

like image 77
clay Avatar answered Oct 18 '22 17:10

clay


Based on the openjdk base image to the gradle image we can see that gradle projects are setup to run in /home/gradle. Check the code out here. gradle run is having trouble running in your new working directory, /code, because the .gradle folder is in the /home/gradle folder. If you copy/add your code into /home/gradle you should be able to run gradle run. This worked for me.

like image 2
Ethan Davis Avatar answered Oct 18 '22 18:10

Ethan Davis