Warum funktioniert Chown nicht in Dockerfile?


84

Meine Docker-Datei erstellt ein Verzeichnis, zeigt es an und listet das Verzeichnis anschließend auf. Das Verzeichnis gehört weiterhin root. Warum das?

Hier ist die Docker-Datei:

FROM ubuntu:precise
RUN useradd -d /home/testuser -m -s /bin/bash testuser
RUN mkdir -p /var/local/testrunner/logs
VOLUME ["/var/local/testrunner/logs"]
RUN grep testuser /etc/passwd
RUN grep root /etc/passwd
RUN chown -R testuser:testuser /var/local/testrunner/logs
RUN ls -ld /var/local/testrunner/logs 

Hier ist die Ausgabe von "Docker Build":

Sending build context to Docker daemon 10.24 kB
Sending build context to Docker daemon 
Step 0 : FROM ubuntu:precise
 ---> ab8e2728644c
Step 1 : RUN useradd -d /home/testuser -m -s /bin/bash testuser
 ---> Using cache
 ---> 640f12671c86
Step 2 : RUN mkdir -p /var/local/testrunner/logs
 ---> Using cache
 ---> bf7756fd5b1f
Step 3 : VOLUME ["/var/local/testrunner/logs"]
 ---> Using cache
 ---> 65c73ee76c20
Step 4 : RUN grep testuser /etc/passwd
 ---> Using cache
 ---> db72fff0b965
Step 5 : RUN grep root /etc/passwd
 ---> Running in ebff78df7a9a
root:x:0:0:root:/root:/bin/bash
 ---> ead0ff704a59
Removing intermediate container ebff78df7a9a
Step 6 : RUN chown -R testuser:testuser /var/local/testrunner/logs
 ---> Running in c925f67b2ab4
 ---> 253132be935e
Removing intermediate container c925f67b2ab4
Step 7 : RUN ls -ld /var/local/testrunner/logs
 ---> Running in 978bc66aa47e
drwxr-xr-x 2 root staff 4096 Oct  1 15:15 /var/local/testrunner/logs

Docker Version 1.2.0, Build fa7b24f

Auf dem Host wird Ubuntu 12.04 ausgeführt, jedoch mit einem 3.13.0-36-generischen Kernel.


2
Für Probleme mit Onership nach COPY siehe: stackoverflow.com/questions/44766665/…
Dieser Brasilianer

Antworten:


125

Beantwortung meiner eigenen Frage: Es wird als Band deklariert. Wenn Sie die VOLUME-Anweisung herausnehmen, wird das Chown wirksam.

Wenn Sie die Lautstärke nach dem Ausführen von Chown deklarieren , bleiben die Chown-Einstellungen wirksam.


17
"Wenn Sie die Lautstärke nach dem Ausführen von Chown deklarieren, bleiben die Chown-Einstellungen wirksam." Dies beantwortete nur etwas, das mich zwei Tage lang verblüfft hatte. Vielen Dank!
CashIsClay

2
Ich antworte mir selbst: Die Erklärung hier ergab für mich container-solutions.com/2014/12/understanding-volumes-docker
Michael Härtl

4
Ein wichtiger Punkt aus diesem Artikel oben: "[Wenn VOLUMEnach einem RUNBefehl angegeben wird, der das Volume ändert], ist Docker clever genug, um alle im Image unter dem Volume-Mount vorhandenen Dateien in das Volume zu kopieren und den Besitz korrekt festzulegen. Dies hat gewonnen Dies passiert nicht, wenn Sie ein Host-Verzeichnis für das Volume angeben (damit Host-Dateien nicht versehentlich überschrieben werden). "
Gezim

2
Die aktualisierte URL für die von @ MichaelHärtl verlinkte Erklärung lautet: blog.container-solutions.com/understanding-volumes-docker
Kamafeather

4
Ich deklariere kein VOLUME in meiner Docker-Datei und habe immer noch dieses Problem ... :-(
fccoelho

8

In diesem Blog http://container42.com/2014/11/03/docker-indepth-volumes/ wird dieses Verhalten ausführlich erläutert.

Jede Anweisung in der Docker-Datei erstellt einen neuen Container. Die Anweisung nimmt einige Änderungen an diesem Container vor und wird zu einer neuen Ebene. Die Änderungen, die vor der Anweisung VOLUME an "/ var / local / testrunner / logs" vorgenommen wurden, wurden am eigentlichen Container-Dateisystem vorgenommen. Nach der Anweisung VOLUME ist das Verzeichnis "/ var / local / testrunner / logs" jedoch das bereitgestellte Verzeichnis. Die Änderungen, die nach der Anweisung VOLUME an diesem Verzeichnis vorgenommen wurden, gelten für das bereitgestellte Verzeichnis und nicht für das eigentliche Container-Dateisystem.


2

Für alle, die dieses Problem ohne Volumen haben , habe ich eine verschlungene Lösung gefunden.

Problem:

Mit einer einfachen Docker-Datei wie folgt:

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

Nach dem Rennen:

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

Die Ausgabe war:

/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

Wie Sie sehen können, ist der Dateieigentum (z. B. test_file.txt) weiterhin dem Benutzer zugeordnet root.

Lösung:

Ich stellte fest, dass ich bei Verwendung einer numerischen UID im chownBefehl den Besitz ändern konnte, aber nur, wenn die UID nicht 1000 war. Also fügte ich 1 zur UID von hinzu new_userund änderte dann den Besitz.

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

Nach dem Rennen:

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

Die Ausgabe war:

/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

Ich bin mir nicht sicher, warum ich dieses Problem überhaupt hatte. Da es jedoch den Anschein hat, dass andere dieses Problem hatten, dachte ich, ich würde meine Problemumgehung veröffentlichen. Mein Anwendungsfall war das Erstellen eines Docker-Containers, der ein Jupyter-Notizbuch bediente. Ich habe einen Benutzer ohne Rootberechtigung erstellt, um das Notebook zu bedienen.


1

Funktioniert meiner Erfahrung nach chownnicht beim Mounten an root ( VOLUME /test). Verwenden Sie einen Nicht-Root-Speicherort ( VOLUME /var/test).


0

Für alpine Linux-Benutzer musste ich chown -R root .in dem Arbeitsbereich arbeiten, den ich besitzen wollte. Dies musste in der CMDDocker-Datei erfolgen, da ich glaube, dass die Volume-Mounts beim Mounten Dateien überschreiben können

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.