why doesn't chown work in Dockerfile?

后端 未结 5 664
日久生厌
日久生厌 2020-12-02 10:44

My Dockerfile creates a directory, chown\'s it, and then lists the directory afterwards. The directory is still owned by root. Why is that?

Here is the Dockerfile:

相关标签:
5条回答
  • 2020-12-02 11:27

    For anyone experiencing this issue without volumes, I found a convoluted work around.

    Problem:

    With a simple Dockerfile as follows:

    FROM ubuntu:16.04
    RUN useradd -m -d /home/new_user new_user
    COPY test_file.txt /home/new_user
    RUN chown -R new_user:new_user /home/new_user
    CMD ls -RFlag /home
    

    After running:

    echo "A file to test permissions." > test_file.txt
    docker build -t chown-test -f Dockerfile .
    docker run --rm -it chown-test
    

    The output was:

    /home:
    total 12
    drwxr-xr-x 1 root 4096 Jun 15 21:37 ./
    drwxr-xr-x 1 root 4096 Jun 15 21:39 ../
    drwxr-xr-x 1 root 4096 Jun 15 21:39 new_user/
    
    /home/new_user:
    total 24
    drwxr-xr-x 1 root 4096 Jun 15 21:39 ./
    drwxr-xr-x 1 root 4096 Jun 15 21:37 ../
    -rw-r--r-- 1 root  220 Aug 31  2015 .bash_logout
    -rw-r--r-- 1 root 3771 Aug 31  2015 .bashrc
    -rw-r--r-- 1 root  655 Jul 12  2019 .profile
    -rw-r--r-- 1 root   28 Jun 11 19:48 test_file.txt
    

    As you can see the file ownership (e.g. test_file.txt) is still associated with user root.

    Solution:

    I found that if I used a numeric UID in the chown command, I could change the ownership, but only if the UID was not 1000. So I added 1 to the UID of new_user and then changed the ownership.

    FROM ubuntu:16.04
    RUN useradd -m -d /home/new_user new_user
    # change the uid of new_user to ensure it has whatever it was assigned plus 1 (e.g. if UID was 1000, now it'll be 1001)
    RUN id -u new_user | awk '{print $1+1}' | xargs -I{} usermod -u {} new_user
    COPY test_file.txt /home/new_user
    RUN id -u new_user | xargs -I{} chown -R {}:{} /home/new_user
    CMD ls -RFlag /home
    

    After running:

    echo "A file to test permissions." > test_file.txt
    docker build -t chown-test -f Dockerfile .
    docker run --rm -it chown-test
    

    The output was:

    /home:
    total 12
    drwxr-xr-x 1 root 4096 Jun 15 21:37 ./
    drwxr-xr-x 1 root 4096 Jun 15 21:37 ../
    drwxr-xr-x 1 1001 4096 Jun 15 21:37 new_user/
    
    /home/new_user:
    total 24
    drwxr-xr-x 1 1001 4096 Jun 15 21:37 ./
    drwxr-xr-x 1 root 4096 Jun 15 21:37 ../
    -rw-r--r-- 1 1001  220 Aug 31  2015 .bash_logout
    -rw-r--r-- 1 1001 3771 Aug 31  2015 .bashrc
    -rw-r--r-- 1 1001  655 Jul 12  2019 .profile
    -rw-r--r-- 1 1001   28 Jun 11 19:48 test_file.txt
    

    I'm not sure why I was having this issue in the first place. However, since it appears others have had this issue, I thought I'd post my workaround. My use case was creating a docker container that served a jupyter notebook. I created a non-root user to serve the notebook.

    0 讨论(0)
  • 2020-12-02 11:29

    For Alpine Linux users, I had to do chown -R root . in the workspace I was trying to own. This had to be done in the CMD of the dockerfile, as I believe the volume mounts may overwrite files when mounting

    0 讨论(0)
  • 2020-12-02 11:30

    In my experience, chown does not work when mounting to root (VOLUME /test). Use a non-root location (VOLUME /var/test).

    0 讨论(0)
  • 2020-12-02 11:31

    This blog http://container42.com/2014/11/03/docker-indepth-volumes/ explains this behaviour in detail.

    Each instruction in the Dockerfile creates a new container. The instruction make some changes to this container and becomes a new layer. The changes made to "/var/local/testrunner/logs" before VOLUME instruction were made to the actual container filesystem. However, after VOLUME instruction, the directory "/var/local/testrunner/logs" is the mounted directory. The changes made to this directory after VOLUME instruction will apply on the mounted directory and not the actual container filesystem.

    0 讨论(0)
  • 2020-12-02 11:41

    Answering my own question: it's declared to be a volume. If you take out the VOLUME instruction, the chown takes effect.

    What's more, if you declare the volume after running chown, the chown settings remain in effect.

    0 讨论(0)
提交回复
热议问题