chmod no funciona correctamente en Docker

18

Estoy creando una imagen de Docker para mi Symfonyaplicación y necesito dar permiso al servidor apache para escribir en la caché y las carpetas de registro

#Dockerfile
FROM php:7-apache

RUN apt-get update \
&& apt-get install -y libicu-dev  freetds-common freetds-bin unixodbc \
&& docker-php-ext-install intl mbstring \
&& a2enmod rewrite

COPY app/php.ini /usr/local/etc/php/
COPY app/apache2.conf /etc/apache2/apache2.conf
COPY ./ /var/www/html

RUN find /var/www/html/ -type d -exec chmod 755 {} \; 
RUN find /var/www/html/ -type f -exec chmod 644 {} \;
RUN chmod -R 777 /var/www/html/app/cache /var/www/html/app/logs

Cuando construyo esta imagen con docker build -t myname/symfony_apps:latest .y ejecuto el contenedor con docker run -p 8080:80 myname/symfony_apps:latest. El registro de Apache está inundado por errores de permiso denegado, lo extraño con lo que he verificado ls -ay los permisos están bien. y cuando ejecuto chmod desde bash del contenedor, los problemas de permisos de apache desaparecen y la aplicación funciona bien

La situación

Ejecución de comandos chmod desde dockerfile: los permisos se cambian, pero apache aún se queja por el permiso denegado. Ejecutando chmod mismos comandos con bash dentro del contenedor: los permisos se cambian y mi aplicación se está ejecutando

¿Alguna idea, me falta algo, tal vez debería agregar un usuario root en algún lugar del Dockerfile?

tormenta
fuente
Sería útil ver su comando docker que ejecuta la imagen construida.
Mike
Veo un espacio extra en su último comando (estoy en mi teléfono, así que no puedo estar seguro). Como el problema del permiso parece estar en el directorio de registro, cambie la última línea a: `` `` RUN chmod -R 777 / var / www / html / app / cache / var / www / html / app / logs '' ``
Mike
1
Ok .. Edité la pregunta :)
tormenta
ese espacio extra era un error tipográfico
tormenta
No puedo reproducir tu problema. Si uso su dockerfile y configuro algunos archivos ficticios localmente, los permisos son correctos y todo funciona. Puedo iniciar un contenedor y acceder al contenido a través de un navegador web. ¿Puedes actualizar tu pregunta para incluir mensajes de error específicos? ¿Está seguro de que su configuración de Apache ( apache2.conf) no está causando un problema? ¿Los errores desaparecen si no los instala apache2.conf?
larsks

Respuestas:

15

Tuve el mismo problema y parece que hay algún error en docker o overlay2 si el contenido del directorio se crea en una capa y sus permisos se cambian en otra.

Como solución alternativa, puede copiar las fuentes al directorio temporal:

COPY . /src

Y luego muévalo /var/www/htmly configure los permisos (en un RUNcomando):

RUN rm -rf /var/www/html && mv /src /var/www/html &&\
    find /var/www/html/ -type d -exec chmod 755 {} \; &&\
    find /var/www/html/ -type f -exec chmod 644 {} \; &&\
    chmod -R 777 /var/www/html/app/cache /var/www/html/app/logs

También creé el problema de GitHub .

Mixel
fuente
Esta noche iba a profundizar en mi antiguo código fuente para ver cómo había resuelto esto, luego recordé ese truco del directorio tmp ... espero que esto no te haya tomado mucho tiempo resolver XD
tormenta
7

El shell predeterminado de RUN en Docker es / bin / sh y aquí es donde los permisos que no se configuran correctamente realmente tienen un problema.

Pero puede cambiar simplemente usar / bin / bash en su lugar para solucionarlo fácilmente, observe antes y después del listado del directorio

Step 7/9 : RUN /bin/bash -c 'ls -la; chmod +x gitlab-properties-builder.sh; ls -la'
---> Running in dc57ae77aa67

drwxr-xr-x. 3 root root      103 Mar  8 17:56 .
drwxr-xr-x. 1 root root       46 Mar  8 17:57 ..
drwxr-xr-x. 2 root root        6 Mar  7 20:47 config
-rw-r--r--. 1 root root     2340 Mar  7 21:20 gitlab-properties-builder.sh
-rw-r--r--. 5 root root 57325770 Mar  5 14:39 gitlab-scm-collector-2.0.5-SNAPSHOT.jar

drwxr-xr-x. 1 root root       42 Mar  8 17:56 .
drwxr-xr-x. 1 root root       61 Mar  8 17:57 ..
drwxr-xr-x. 2 root root        6 Mar  7 20:47 config
-rwxr-xr-x. 1 root root     2340 Mar  7 21:20 gitlab-properties-builder.sh
-rw-r--r--. 5 root root 57325770 Mar  5 14:39 gitlab-scm-collector-2.0.5-SNAPSHOT.jar
---> 8b5de6e348d3
Thad Guidry
fuente
2
¿Por qué está /bin/bash -c 'chmod +x file'funcionando y no /bin/sh -c 'chmod +x file'?
tormenta
Tu es la mejor solución. Funcionó para mí. Gracias .
user1427944
Además, el uso del nuevo buildkit ayuda en varias áreas, incluida esta. Darle una oportunidad. docs.docker.com/develop/develop-images/build_enhancements
Thad Guidry
5

Intenta agregar:

USER root

Funcionó para mi.

secavfr
fuente
Esta debería ser la respuesta aceptada.
Vladimir Kornea 01 de
2
Si cambia a root, probablemente debería volver al usuario anterior cuando termine o está disminuyendo la seguridad y compatibilidad del contenedor. Algunas implementaciones de Kubernetes por defecto no ejecutarán un contenedor como root, por ejemplo.
flickerfly
2

Es probable que este problema sea el resultado de una VOLUMEdefinición dentro del Dockerfile ascendente. Cuando se define un volumen en el Dockerfile, puede agregar archivos con un comando COPYo ADDdirectamente en la imagen. Sin embargo, una RUNlínea:

  • Cree un contenedor temporal utilizando la definición de imagen a partir del punto actual del dockerfile
    • Ese contenedor temporal tendrá un volumen anónimo montado como usted o una imagen principal especificada dentro del Dockerfile
    • El volumen anónimo se inicializará a partir del contenido de la imagen.
  • Su comando se ejecutará dentro del contenedor.
    • Si enumera el directorio durante este RUNcomando, verá sus cambios aplicados, pero esos cambios se han aplicado al volumen
  • Cuando se complete su comando de ejecución, Docker capturará los cambios en el contenedor
    • Estos cambios se pueden ver con un docker diffsi no elimina los contenedores temporales (puede ejecutar una compilación --rm=falsepara que permanezcan)
    • Estos cambios no incluirán el contenido del volumen anónimo porque no existen dentro del sistema de archivos del contenedor temporal, los volúmenes están separados

Debido a este comportamiento, tiene las opciones para:

  1. puedes copiar tus archivos a un directorio diferente y cambiar los permisos allí
  2. puede corregir los permisos en su host para que se copien directamente con esos permisos
  3. puede eliminar el volumen de su imagen, obtener la imagen ascendente para eliminar su definición de volumen, o puede reconstruir su propia copia de la imagen ascendente sin la definición de volumen y basar sus imágenes en eso

Tenga en cuenta que dentro de las imágenes php actuales, parece que se ha eliminado el volumen, lo que significa que efectivamente tenemos la opción 3.

BMitch
fuente
0

Acabo de hacer un experimento con lo siguiente:

FROM alpine

LABEL MAINTAINER="YIMGA YIMGA Salathiel Genèse"
RUN apk add --no-cache inotify-tools
CMD [ "./script.sh" ]
WORKDIR /opt/app/
COPY src/ /opt/app/
RUN chmod a+x *.sh

Y simplemente funciona muy bien.

sin embargo

Cuando anulo ese archivo ejecutable a través de volúmenes compuestos por docker, el executepermiso es simplemente como revertido: técnicamente anula el permiso de archivo original.

La solución para el modo de desarrollo es simplemente chmod a+x yourfiledesde el host, que se heredará al componer el montaje del volumen.

Salathiel Genèse
fuente
1
El objetivo completo de un volumen es montar archivos desde otro lugar que no sea la imagen, por lo que si arregla su imagen y monta un volumen por encima de eso, por diseño no verá cambios en su imagen. Dependiendo de por qué tiene un volumen, la respuesta puede ser simplemente no tener un volumen.
BMitch
BMitch , estoy totalmente de acuerdo en cuanto al efecto del volumen de montaje que anula el contenedor fs de la imagen construida en la ventana acoplable, pero ... Durante el desarrollo, seguramente no querrá reconstruir / reiniciar su contenedor para probar cada cambio que realice. hacer. En este último escenario, ¿desea que se monte un volumen que anula la imagen construida por docker fs. Y me enfrenté al mismo problema antes de aterrizar aquí. No fui condenado por ninguna de las explicaciones de respuesta y probé cada una de ellas. Solo entonces comprendí lo que sucedía y publiqué mis observaciones ...
Salathiel Genèse
... y sospecho que el escenario que experimenté es el mismo que el del que hizo la pregunta.
Salathiel Genèse
El OP indicó que vieron el problema con solo un docker runcomando y sin montajes de volumen externos.
BMitch
Oups: me perdí ese aspecto ... La respuesta correcta para el título correcto de la pregunta, pero no el escenario descrito. Entonces puedo mencionar que no pude reproducir el problema mencionado anteriormente.
Salathiel Genèse el