chmod ne fonctionne pas correctement dans Docker

18

Je crée une image Docker pour mon Symfonyapplication et je dois autoriser le serveur Apache à écrire dans les dossiers de cache et de journal

#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

Lorsque je crée cette image avec docker build -t myname/symfony_apps:latest .et exécute le conteneur avec docker run -p 8080:80 myname/symfony_apps:latest. Le journal Apache est inondé d'erreurs d'autorisation refusée, la chose étrange avec laquelle j'ai vérifié ls -aet les autorisations sont très bien. et quand j'exécute chmod depuis bash du conteneur, les problèmes d'autorisation apache ont disparu et l'application fonctionne bien

La situation

Exécution des commandes chmod à partir de dockerfile: les autorisations sont modifiées mais apache se plaint toujours de l'autorisation refusée. Exécution de mêmes commandes chmod avec bash à l'intérieur du conteneur: les autorisations sont modifiées et mon application est en cours d'exécution

Une idée, est-ce que je manque quelque chose, peut-être devrais-je ajouter un utilisateur root quelque part dans le Dockerfile?

tempête
la source
Il serait utile de voir votre commande docker qui exécute l'image construite.
Mike
Je vois un espace supplémentaire dans votre dernière commande (je suis sur mon téléphone, donc je ne peux pas en être sûr). Comme le problème d'autorisation semble être lié au répertoire des journaux, remplacez la dernière ligne par: `` `RUN chmod -R 777 / var / www / html / app / cache / var / www / html / app / logs` `
Mike
1
D'accord .. J'ai édité la question :)
storm
cet espace supplémentaire était une faute de frappe
tempête
Je n'arrive pas à reproduire votre problème. Si j'utilise votre dockerfile et que je configure des fichiers factices localement, les autorisations sont correctes et tout fonctionne correctement. Je peux démarrer un conteneur et accéder au contenu via un navigateur Web. Pouvez-vous mettre à jour votre question pour inclure des messages d'erreur spécifiques? Êtes-vous certain que votre configuration Apache ( apache2.conf) ne pose pas de problème? Les erreurs disparaissent-elles si vous n'installez pas apache2.conf?
larsks

Réponses:

15

J'ai eu le même problème et il semble qu'il y ait un bug dans docker ou overlay2 si le contenu du répertoire est créé dans une couche et ses autorisations sont modifiées dans l'autre.

Pour contourner ce problème, vous pouvez copier les sources dans un répertoire temporaire:

COPY . /src

Ensuite, déplacez-le /var/www/htmlet configurez les autorisations (dans une seule RUNcommande):

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

J'ai également créé le problème GitHub .

mixel
la source
J'allais fouiller dans mon ancien code source cette nuit pour voir comment j'ai résolu cela, puis je me suis souvenu de cette astuce dans le répertoire tmp .. j'espère que cela ne vous a pas pris beaucoup de temps pour résoudre XD
storm
7

Le shell par défaut de RUN dans Docker est / bin / sh et c'est là que les autorisations qui ne sont pas définies correctement ont réellement un problème.

Mais vous pouvez changer pour utiliser simplement / bin / bash à la place pour facilement corriger, remarquer avant et après la liste des répertoires

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
la source
2
Pourquoi ça /bin/bash -c 'chmod +x file'marche et pas /bin/sh -c 'chmod +x file'?
tempête
votre meilleure solution. ça a marché pour moi. Merci .
user1427944
En outre, l'utilisation du nouveau buildkit aide dans un certain nombre de domaines, y compris celui-ci. Essaie. docs.docker.com/develop/develop-images/build_enhancements
Thad Guidry
5

Essayez d'ajouter:

USER root

Ça a marché pour moi.

secavfr
la source
Cela devrait être la réponse acceptée.
Vladimir Kornea
2
Si vous basculez vers root, vous devez probablement revenir à l'utilisateur précédent lorsque vous avez terminé ou vous diminuez la sécurité et la compatibilité du conteneur. Par exemple, certaines implémentations de Kubernetes n'exécutent pas de conteneur en tant que root.
flickerfly
2

Ce problème est probablement le résultat d'une VOLUMEdéfinition à l'intérieur du Dockerfile en amont. Lorsqu'un volume est défini dans le Dockerfile, vous pouvez ajouter des fichiers avec une commande COPYou ADDdirectement dans l'image. Cependant, une RUNligne:

  • Créer un conteneur temporaire en utilisant la définition d'image à partir du point actuel du dockerfile
    • Ce conteneur temporaire aura un volume anonyme monté comme vous ou une image parent spécifiée dans le Dockerfile
    • Le volume anonyme sera initialisé à partir du contenu de l'image
  • Votre commande s'exécutera à l'intérieur du conteneur
    • Si vous répertoriez le répertoire au cours de cette RUNcommande, vous verrez vos modifications appliquées, mais ces modifications ont été appliquées au volume
  • Lorsque votre commande d'exécution se termine, docker capture les modifications apportées au conteneur
    • Ces modifications sont visibles avec un docker diffsi vous ne supprimez pas les conteneurs temporaires (vous pouvez exécuter une génération avec --rm=falsepour les conserver)
    • Ces modifications n'incluront pas le contenu du volume anonyme car elles n'existent pas à l'intérieur du système de fichiers du conteneur temporaire, les volumes sont séparés

En raison de ce comportement, vous avez les options suivantes:

  1. vous pouvez copier vos fichiers dans un autre répertoire et y modifier les autorisations
  2. vous pouvez fixer les autorisations sur votre hôte afin qu'il soit copié directement avec ces autorisations
  3. vous pouvez supprimer le volume de votre image, obtenir l'image en amont pour supprimer leur définition de volume, ou vous pouvez reconstruire votre propre copie de l'image en amont sans la définition du volume et baser vos images sur celle-ci

Notez qu'à l'intérieur des images php actuelles, il semble que le volume a été supprimé, ce qui signifie que nous avons effectivement l'option 3.

BMitch
la source
0

Je viens de faire une expérience avec les éléments suivants:

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

Et cela fonctionne très bien.

pourtant

Lorsque je remplace ce fichier exécutable via des volumes de composition de docker, l' executeautorisation est tout simplement comme annulée - techniquement remplacée par l'autorisation de fichier d'origine.

Le correctif pour le mode dev est simplement chmod a+x yourfilede l'hôte, qui sera hérité lors du montage du volume de composition.

Salathiel Genèse
la source
1
L'objectif d'un volume est de monter des fichiers ailleurs que sur l'image, donc si vous corrigez votre image et montez un volume par-dessus, par conception, vous ne verrez pas les changements d'image. Selon la raison pour laquelle vous avez un volume, la réponse peut être simplement de ne pas avoir de volume.
BMitch
Oui BMitch , je suis totalement d'accord quant à l'effet du volume de montage qui remplace le conteneur fs à partir de l'image construite par docker, mais ... Pendant le développement, vous ne voulez sûrement pas reconstruire / redémarrer votre conteneur afin de tester chaque changement que vous faire. Dans ce dernier scénario, voulez-vous monter un volume qui remplace les images construites par docker fs. Et j'ai fait face au même problème avant d'atterrir ici. Je n'ai pas été reconnu coupable par l'une ou l'autre des explications de réponse et testé chacun d'eux. Ce n'est qu'à ce moment-là que j'ai compris ce qui se passait et posté mes observations ...
Salathiel Genèse
... et je soupçonne que le scénario que j'ai vécu est le même que celui de celui qui a posé la question.
Salathiel Genèse
L'OP a indiqué avoir vu le problème avec juste une docker runcommande et aucun montage de volume externe.
BMitch
Oups - J'ai raté cet aspect ... La bonne réponse pour le bon titre de question, mais pas le scénario décrit. Puis-je mentionner que je n'ai pas pu reproduire le problème mentionné ci-dessus.
Salathiel Genèse