¿Por qué chown no funciona en Dockerfile?

84

Mi Dockerfile crea un directorio, lo usa y luego enumera el directorio. El directorio sigue siendo propiedad de root. ¿Porqué es eso?

Aquí está el 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 

Aquí está el resultado de "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 versión 1.2.0, compilación fa7b24f

El host ejecuta Ubuntu 12.04, pero con un kernel genérico 3.13.0-36.

usuario100464
fuente
2
Para problemas con el envío después de COPY, consulte: stackoverflow.com/questions/44766665/…
Ese tipo brasileño

Respuestas:

125

Respondiendo a mi propia pregunta: se declara que es un volumen. Si saca la instrucción VOLUME, el chown entra en vigor.

Es más, si declara el volumen después de ejecutar chown, la configuración de chown permanece vigente.

usuario100464
fuente
17
"Si declaras el volumen después de ejecutar chown, la configuración de chown permanece en efecto" Esto acaba de responder a algo que me ha dejado perplejo durante dos días. ¡Gracias!
CashIsClay
2
Respondiendo a mí mismo: La explicación aquí tiene sentido para mí container-solutions.com/2014/12/understanding-volumes-docker
Michael Härtl
4
Un punto importante del artículo anterior: "[Cuando VOLUMEse especifica después de un RUNcomando que modifica el volumen], la ventana acoplable es lo suficientemente inteligente como para copiar cualquier archivo que exista en la imagen debajo del montaje del volumen en el volumen y establecer la propiedad correctamente. Esto ganó no sucede si especifica un directorio de host para el volumen (para que los archivos de host no se sobrescriban accidentalmente) "
Gezim
2
La URL actualizada para la explicación vinculada por @ MichaelHärtl es: blog.container-solutions.com/understanding-volumes-docker
Kamafeather
4
No declaro ningún VOLUMEN en mi dockerfile y todavía tengo este problema ... :-(
fccoelho
8

Este blog http://container42.com/2014/11/03/docker-indepth-volumes/ explica este comportamiento en detalle.

Cada instrucción en el Dockerfile crea un nuevo contenedor. La instrucción realiza algunos cambios en este contenedor y se convierte en una nueva capa. Los cambios realizados en "/ var / local / testrunner / logs" antes de la instrucción VOLUME se realizaron en el sistema de archivos contenedor real. Sin embargo, después de la instrucción VOLUME, el directorio "/ var / local / testrunner / logs" es el directorio montado. Los cambios realizados en este directorio después de la instrucción VOLUME se aplicarán al directorio montado y no al sistema de archivos contenedor real.

duende
fuente
2

Para cualquiera que experimente este problema sin volúmenes , encontré una solución complicada.

Problema:

Con un simple Dockerfile de la siguiente manera:

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

Despues de correr:

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

El resultado fue:

/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

Como puede ver, la propiedad del archivo (por ejemplo, test_file.txt) todavía está asociada con el usuario root.

Solución:

Descubrí que si usaba un UID numérico en el chowncomando, podía cambiar la propiedad, pero solo si el UID no era 1000. Así que agregué 1 al UID de new_usery luego cambié la propiedad.

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

Despues de correr:

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

El resultado fue:

/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

No estoy seguro de por qué estaba teniendo este problema en primer lugar. Sin embargo, dado que parece que otros han tenido este problema, pensé en publicar mi solución. Mi caso de uso fue la creación de un contenedor de ventana acoplable que sirvió a un cuaderno jupyter. Creé un usuario no root para servir el portátil.

Hari S. Khalsa
fuente
1

En mi experiencia, chownno funciona cuando se monta en root ( VOLUME /test). Utilice una ubicación que no sea root ( VOLUME /var/test).

Miguel
fuente
0

Para los usuarios de Alpine Linux , tenía que hacerlo chown -R root .en el espacio de trabajo que intentaba tener. Esto tenía que hacerse en el CMDdockerfile, ya que creo que los montajes de volumen pueden sobrescribir los archivos al montar

mateos
fuente