Docker image permission issue

Hi

I tried to create Dockerfile to build my project:

FROM gradle:4.4-jdk9

COPY . /home/gradle/project/ 

WORKDIR /home/gradle/project/

RUN gradle clean build

However when I build this Dockerfile the last instruction fails with error message:

Caused by: org.gradle.api.UncheckedIOException: Failed to create parent directory '/home/gradle/project/.gradle' when creating directory '/home/gradle/project/.gradle/4.4/fileHashes'
        at org.gradle.util.GFileUtils.mkdirs(GFileUtils.java:271)
        at org.gradle.cache.internal.DefaultPersistentDirectoryStore.open(DefaultPersistentDirectoryStore.java:56)
        at org.gradle.cache.internal.DefaultPersistentDirectoryStore.open(DefaultPersistentDirectoryStore.java:32)
        at org.gradle.cache.internal.DefaultCacheFactory.doOpen(DefaultCacheFactory.java:90)
        at org.gradle.cache.internal.DefaultCacheFactory.open(DefaultCacheFactory.java:64)
        at org.gradle.cache.internal.DefaultCacheRepository$PersistentCacheBuilder.open(DefaultCacheRepository.java:123)

When I run Docker container without Dockerfile everything is fine:

docker run -it --rm -v "d:\Project":/home/gradle/project -w /home/gradle/project gradle:4.4-jdk9 gradle clean build

When you copy files to /home/gradle/project, all rights belongs to root user. You can test it, if you insert RUN ls -la /home/gradle before you run command.

To fix this issue you have 2 options:

  • change user to root, then your Dockerfile will be looks so
    FROM gradle:4.4-jdk9
    COPY . /home/gradle/project
    USER root
    WORKDIR /home/gradle/project/
    RUN gradle clean build
    
  • or change permissions of your project folder, then your Dockerfile will be look so
    FROM gradle:4.4-jdk9
    COPY . /home/gradle/project/
    WORKDIR /home/gradle/project/
    
    USER root
    RUN chown -R gradle /home/gradle/project
    USER gradle
    
    RUN gradle clean build
    

Which variant is better depends on your use case.

Hi

Thank you for the quick response. I already chose first approach.
But the question still remains. Why did you introduce gradle user in your Dockerfile if we have to switch to root user in any case?

The Dockerfile was created and is maintained by a user that found it to be useful and wanted to share, not the Gradle core team or community members that frequent the forums and regularly answer questions. The maintainer will probably not see this thread.

Docker best practices say run as an unprivileged user when possible. Switching back to root is certainly an option, but there are other options, including the optional --chown parameter when you copy the files to the container (different than running chown as root).

hey-hey, about your questions.

I didn’t introduce gradle user it comes from official Docker image (https://github.com/keeganwitt/docker-gradle/blob/b0419babd3271f6c8e554fbc8bbd8dc909936763/jdk9/Dockerfile#L35) and COPY and ADD commands had bugs with permissions. It looks like it was fixed (https://github.com/moby/moby/pull/34263), therefore second approach is simple workaround.

P.S. Your final Docker image will be really huge, why not using multi-stage builds (https://docs.docker.com/engine/userguide/eng-image/multistage-build/) and Gradle wrapper?