3

I am running a build in a gradle container with a volume for the cache, but gradle does not make use of the downloaded dependencies in the cache for the subsequent builds.

Here's the dockerfile for the gradle image:

FROM **custom image base**

# Install the Java Development Kit
RUN apk --no-cache add openjdk8=8.131.11-r2

CMD ["gradle"]

ENV GRADLE_HOME /opt/gradle
ENV GRADLE_VERSION 4.6

ARG GRADLE_DOWNLOAD_SHA256=98bd5fd2b30e070517e03c51cbb32beee3e2ee1a84003a5a5d748996d4b1b915
RUN set -o errexit -o nounset \
        && echo "Installing build dependencies" \
        && apk add --no-cache --virtual .build-deps \
                ca-certificates \
                openssl \
                unzip \
        \
        && echo "Downloading Gradle" \
        && wget -O gradle.zip "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" \
        \
        && echo "Checking download hash" \
        && echo "${GRADLE_DOWNLOAD_SHA256} *gradle.zip" | sha256sum -c - \
        \
        && echo "Installing Gradle" \
        && unzip gradle.zip \
        && rm gradle.zip \
        && mkdir /opt \
        && mv "gradle-${GRADLE_VERSION}" "${GRADLE_HOME}/" \
        && ln -s "${GRADLE_HOME}/bin/gradle" /usr/bin/gradle \
        \
        && apk del .build-deps \
        \
        && echo "Adding gradle user and group" \
        && addgroup -S -g 1000 gradle \
        && adduser -D -S -G gradle -u 1000 -s /bin/ash gradle \
        && mkdir /home/gradle/.gradle \
        && chown -R gradle:gradle /home/gradle \
        \
        && echo "Symlinking root Gradle cache to gradle Gradle cache" \
        && ln -s /home/gradle/.gradle /root/.gradle

# Create Gradle volume
USER gradle
VOLUME "/home/gradle/.gradle"
WORKDIR /home/gradle

RUN set -o errexit -o nounset \
        && echo "Testing Gradle installation" \
        && gradle --version

In the Jenkinsfile I have the build stage declared like this:

stage('Build') {
        docker.image('custom-gradle').withRun('-v gradle-cache:/home/gradle/.gradle') { c ->
            docker.image('custom-gradle').inside {
                sh './scripts/build.py -br ' + branchName
                sh 'cp build/libs/JARFILE*.jar build/libs/JARFILE.jar'
            }
        }
    }

The 'gradle-cache' volume is a volume that was created with the docker volume create command.

The python script just runs a gradle command:

gradle clean assemble javaDoc

When I inspect the gradle-cache volume data on the host machine it contains the following files/folders:

4.6  buildOutputCleanup  caches  daemon  native

So the build successfully writes to the cache volume, but appears not to read from it, re-downloading every dependency for every build.

How can I get gradle to use these downloaded dependencies?

UPDATE

stage('Build Bag End') {
        docker.image('custom-gradle').inside('-v gradle-cache:/home/gradle/.gradle') {
            sh './scripts/build.py -br ' + branchName
            sh 'cp build/libs/JARFILE*.jar build/libs/JARFILE.jar'
        }
    }

So I found the .inside() command also supports parameters but it still won't read from the cache; only write to it.

Oromë
  • 199
  • 2
  • 16

1 Answers1

0

I believe that Jenkins Docker Plugin always runs containers as the jenkins user. It looks like your gradle image is assuming that it is running as the gradle user. You might try adding the following option:

-e GRADLE_USER_HOME=/home/gradle/.gradle

Though you might run into permission issues with that.

Cosmin Staicu
  • 1,809
  • 2
  • 20
  • 27