dlaczego chown nie działa w Dockerfile?

85

Mój plik Dockerfile tworzy katalog, chown to, a następnie wyświetla listę katalogu. Katalog nadal jest własnością roota. Dlaczego?

Oto plik Dockerfile:

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 

Oto wynik działania „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 w wersji 1.2.0, kompilacja fa7b24f

Na hoście działa Ubuntu 12.04, ale z jądrem w wersji 3.13.0-36.

user100464
źródło
2
W przypadku problemów z samodzielnością po COPY, patrz: stackoverflow.com/questions/44766665/…
Ten Brazylijczyk

Odpowiedzi:

127

Odpowiadając na moje własne pytanie: zadeklarowano, że jest to tom. Jeśli wyjmiesz instrukcję VOLUME, zmiana zacznie obowiązywać.

Co więcej, jeśli zadeklarujesz głośność po uruchomieniu chown, ustawienia chown pozostaną aktywne.

user100464
źródło
18
„Jeśli zadeklarujesz głośność po uruchomieniu chown, ustawienia chown pozostają w mocy”. To właśnie odpowiedział na coś, co mnie potknęło przez dwa dni. Dziękuję Ci!
CashIsClay
2
Odpowiadając sobie: Wyjaśnienie tutaj miało dla mnie sens container-solutions.com/2014/12/understanding-volumes-docker
Michael Härtl
4
Ważny punkt z powyższego artykułu: „[Gdy VOLUMEjest określone po RUNpoleceniu modyfikującym wolumin], docker jest na tyle sprytny, że kopiuje do woluminu wszystkie pliki, które istnieją w obrazie pod woluminem, i ustawia ich własność. Wygrał. nie dzieje się tak, jeśli określisz katalog hosta dla woluminu (aby pliki hosta nie zostały przypadkowo nadpisane).
Gezim
2
Zaktualizowany adres URL do wyjaśnienia, do którego prowadzi @ MichaelHärtl, to: blog.container-solutions.com/understanding-volumes-docker
Kamafeather
5
Nie deklaruję żadnych VOLUME w moim pliku dockerfile i nadal mam ten problem ... :-(
fccoelho
8

Ten blog http://container42.com/2014/11/03/docker-indepth-volumes/ szczegółowo wyjaśnia to zachowanie.

Każda instrukcja w pliku Dockerfile tworzy nowy kontener. Instrukcja wprowadza pewne zmiany w tym kontenerze i staje się nową warstwą. Zmiany wprowadzone w „/ var / local / testrunner / logs” przed instrukcją VOLUME zostały wprowadzone w rzeczywistym systemie plików kontenera. Jednak po instrukcji VOLUME katalog „/ var / local / testrunner / logs” jest katalogiem zamontowanym. Zmiany dokonane w tym katalogu po instrukcji VOLUME będą miały zastosowanie do zamontowanego katalogu, a nie do rzeczywistego systemu plików kontenera.

chochlik
źródło
2

Dla każdego, kto ma ten problem bez woluminów , znalazłem zawiłą obejście.

Problem:

Z prostym plikiem Dockerfile w następujący sposób:

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

Po bieganiu:

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

Wynik był:

/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

Jak widać, własność pliku (np. Test_file.txt) jest nadal powiązana z użytkownikiem root .

Rozwiązanie:

Stwierdziłem, że jeśli użyję numerycznego UID w chownpoleceniu, mogę zmienić właściciela, ale tylko wtedy, gdy UID nie wynosi 1000. Więc dodałem 1 do UID, new_usera następnie zmieniłem właściciela.

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

Po bieganiu:

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

Wynik był:

/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

Nie jestem pewien, dlaczego miałem ten problem w pierwszej kolejności. Ponieważ jednak wydaje się, że inni mieli ten problem, pomyślałem, że opublikuję moje obejście. Moim przypadkiem użycia było utworzenie kontenera docker, który obsługiwał notatnik jupyter. Utworzyłem użytkownika innego niż root do obsługi notebooka.

Hari S. Khalsa
źródło
1

Z mojego doświadczenia chownwynika , że nie działa podczas montowania do roota ( VOLUME /test). Użyj lokalizacji innej niż root ( VOLUME /var/test).

Mikrofon
źródło
0

Dla użytkowników Alpine Linux musiałem pracować chown -R root .w obszarze roboczym, który próbowałem posiadać. CMDMusiało to być zrobione w pliku dockerfile, ponieważ uważam, że montowanie woluminów może nadpisać pliki podczas montowania

mateos
źródło