How to add a file to a docker container which has no root permissions?

56,207

Solution 1

There is likely a way to view and change the Dockerfile for tomcat, but I can't figure it out after a few minutes. My inelegant solution is to add this line before the chown:

USER root

If you want to de-elevate the privileges after (which is recommended) you could add this line:

USER tomcat

Alternately, work with an image that has no software installed so you can begin your Dockerfile as root and install tomcat and all that. It's actually odd they change that in their image from my experience. It makes sense to allow the intended end user to set the USER directive as they see fit.

Solution 2

Since Docker 17.09 one can use the --chown flag on ADD/COPY operations in Dockerfile to change the owner in the ADD/COPY step itself rather than a separate RUN operation with chown which increases the size of the image as you have noted. It would have been good to have this as the default mode i.e. the permissions of the user copying the files are applied to the copied files. However, the Docker team did not want to break backward compatibility and hence introduced a new flag.

COPY --chown=<user>:<group> <hostPath> <containerPath>

The other alternatives are:

  1. Change the permission in a staging folder prior to building the image.
  2. Run the container via a bootstrap script that changes the ownership.
  3. Squash the layers!
Share:
56,207

Related videos on Youtube

nyi
Author by

nyi

Updated on September 18, 2022

Comments

  • nyi
    nyi over 1 year

    I'm trying to add a file to a Docker image built from the official tomcat image. That image does not seem to have root rights, as I'm logged in as user tomcat if I run bash:

    docker run -it tomcat /bin/bash
    tomcat@06359f7cc4db:/usr/local/tomcat$ 
    

    If I instruct a Dockerfile to copy a file to that container, the file has permissions 644 and the owner is root. As far as I understand, that seems to be reasonable as all commands in the Dockerfile are run as root. However, if I try to change ownership of that file to tomcat:tomcat, I get a Operation not permitted error.

    Why can't I change the permissions of a file copied to that image?

    How it can be reproduced:

    mkdir docker-addfilepermission
    cd docker-addfilepermission
    touch test.txt
    echo 'FROM tomcat
    COPY test.txt /usr/local/tomcat/webapps/
    RUN chown tomcat:tomcat /usr/local/tomcat/webapps/test.txt' > Dockerfile
    
    docker build .
    

    The output of docker build .:

    Sending build context to Docker daemon 3.072 kB
    Sending build context to Docker daemon 
    Step 0 : FROM tomcat
     ---> 44859847ef64
    Step 1 : COPY test.txt /usr/local/tomcat/webapps/
     ---> Using cache
     ---> a2ccb92480a4
    Step 2 : RUN chown tomcat:tomcat /usr/local/tomcat/webapps/test.txt
     ---> Running in 208e7ff0ec8f
    chown: changing ownership of '/usr/local/tomcat/webapps/test.txt': Operation not permitted
    2014/11/01 00:30:33 The command [/bin/sh -c chown tomcat:tomcat /usr/local/tomcat/webapps/test.txt] returned a non-zero code: 1
    
  • nyi
    nyi over 9 years
    This indeed works! Do you know by chance why the ADD and COPY commands create files with owner root? Why don't they take the USER directive into account?
  • theterribletrivium
    theterribletrivium over 9 years
    Well, typically you don't see base images setting the directive, as there is no real way to know what user accounts will be on the system. It also might be easier to just have the files be created as root since that's what Docker has to run as. It seems like a reasonable enhancement request, it would simplify building Dockerfiles if things could automatically be owned by what was set in the USER directive.
  • Kostas Demiris
    Kostas Demiris about 7 years
    Thanks.Really put me out of my misery. I needed to add ssh keys in a Jenkins image.