2

After investigating usermod, this, github there seems to no acceptable way to enable spring boot write access to /opt/service/log directory/volume which ends up in java.io.FileNotFoundException: log/app.log (Permission denied).

Dockerfile:

FROM openjdk:8-alpine
RUN apk update && apk add --no-cache bash curl busybox
EXPOSE 8080
#1 RUN mkdir -p /opt/service/log ; chown -R user /opt/service/log  
VOLUME ["/opt/service/log"]
# a few COPY commands
RUN adduser -D -S -u 1000 user && chown -R 1000 /opt/service/
#2 RUN chmod -R 777 /opt/service

RUN chmod 755 /opt/service/entrypoint.sh

USER 1000
RUN ls -la .
RUN touch /opt/service/log/test.log

ENTRYPOINT ["/opt/service/entrypoint.sh"]

#1 this commented fix works but is not acceptable since the directory can be changed later on.

The output of executing Dockerfile:

[INFO] DOCKER> Step 13/15 : RUN ls -la .
[INFO] DOCKER> 
[INFO] DOCKER> ---> Running in a99022c07da2
[INFO] DOCKER> total 28088
drwxr-xr-x    1 user   root          4096 Oct 15 11:05 .
drwxr-xr-x    1 root     root          4096 Oct 15 11:02 ..
-rw-r--r--    1 user   root          4367 Sep 17 10:18 entrypoint.sh
drwxr-xr-x    2 root     root          4096 Oct 15 11:05 log
-rw-r--r--    1 user   root      28741050 Oct 15 11:05 service.jar
[INFO] DOCKER> Removing intermediate container a99022c07da2
[INFO] DOCKER> ---> d0831197c79c
[INFO] DOCKER> Step 14/15 : RUN touch /opt/service/log/test.log
[INFO] DOCKER> 
[INFO] DOCKER> ---> Running in 54f5d57499fc
[INFO] DOCKER> [91mtouch: /opt/service/log/test.log: Permission denied

How to make volume writable by user user / spring boot?

J.Olufsen
  • 13,415
  • 44
  • 120
  • 185

1 Answers1

1

You defined /opt/service/log as a volume. Once you have done that, no further changes are possible from RUN commands. The recursive chmod will run, in a temporary container with a temporary anonymous volume mounted, and then the anonymous volume is discarded along with the permission changes you've made.

This is detailed in the Dockerfile documentation:

  • Changing the volume from within the Dockerfile: If any build steps change the data within the volume after it has been declared, those changes will be discarded.

My best practice is to remove the VOLUME definition from the Dockerfile entirely because it causes issues like this, and breaks the ability for downstream users to make changes. You can always define a volume mount in your docker-compose.yml or docker run command line, at run time, rather than when building the image. If you must define the volume inside your Dockerfile, then move it to the end of the file, and realize that you will break the ability to extend this image in a later Dockerfile.

BMitch
  • 231,797
  • 42
  • 475
  • 450