chmod funktioniert in Docker nicht richtig

17

Ich erstelle ein Docker-Image für meine SymfonyApp und muss dem Apache-Server die Berechtigung zum Schreiben in Cache- und Protokollordner erteilen

#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

Wenn ich dieses Image mit erstelle docker build -t myname/symfony_apps:latest .und den Container mit ausführe docker run -p 8080:80 myname/symfony_apps:latest. Das Apache-Protokoll wird von Fehlern überflutet, denen die Berechtigung verweigert wurde. Das Seltsame, mit dem ich nachgefragt habe, ls -aund die Berechtigungen sind in Ordnung. und wenn ich chmod von Containers Bash aus starte, sind Probleme mit der Apache-Berechtigung verschwunden und die App funktioniert gut

Die Situation

Ausführen von chmod-Befehlen aus der Docker-Datei: Berechtigungen werden geändert, aber Apache beschwert sich weiterhin über verweigerte Berechtigungen. Ausführen von chmod gleichen Befehlen mit bash im Container: Berechtigungen werden geändert und meine App wird ausgeführt

Irgendeine Idee, vermisse ich etwas, vielleicht sollte ich irgendwo in der Docker-Datei Root-Benutzer hinzufügen?

Sturm
quelle
Es wäre hilfreich, Ihren Docker-Befehl zu sehen, mit dem das erstellte Image ausgeführt wird.
Mike
In Ihrem letzten Befehl wird ein zusätzliches Leerzeichen angezeigt (ich bin auf meinem Telefon, daher kann ich nicht sicher sein). Da das Berechtigungsproblem im Protokollverzeichnis zu liegen scheint, ändern Sie die letzte Zeile in: `` `RUN chmod -R 777 / var / www / html / app / cache / var / www / html / app / logs` ``
Mike
1
Okay .. Ich habe die Frage bearbeitet :)
Sturm
Dieser zusätzliche Platz war ein Tippfehler
Sturm
Ich kann Ihr Problem nicht reproduzieren. Wenn ich Ihre Docker-Datei verwende und einige Dummy-Dateien lokal einrichte, sind die Berechtigungen korrekt und alles funktioniert einfach. Ich kann einen Container booten und über einen Webbrowser auf Inhalte zugreifen. Können Sie Ihre Frage so aktualisieren, dass sie bestimmte Fehlermeldungen enthält? Sind Sie sicher, dass Ihre Apache-Konfiguration ( apache2.conf) kein Problem verursacht? Verschwinden die Fehler, wenn Sie nicht installieren apache2.conf?
Larsks

Antworten:

15

Ich hatte das gleiche Problem und es scheint, dass es einen Fehler in Docker oder Overlay2 gibt, wenn Verzeichnisinhalte in einer Ebene erstellt und deren Berechtigungen in einer anderen geändert werden.

Um dieses Problem zu umgehen, können Sie Quellen in ein temporäres Verzeichnis kopieren:

COPY . /src

Verschieben Sie es dann zu /var/www/htmlund richten Sie die Berechtigungen ein (in einem RUNBefehl):

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

Außerdem habe ich ein GitHub-Problem erstellt .

mischen
quelle
Ich wollte mich heute Abend in meinen alten Quellcode vertiefen, um zu sehen, wie ich das gelöst habe, dann erinnerte ich mich an diesen Trick mit dem TMP-Verzeichnis. Ich hoffe, Sie haben nicht viel Zeit gebraucht, um XD
Storm
6

Die Standard-Shell von RUN in Docker ist / bin / sh. Hier haben die nicht richtig eingestellten Berechtigungen tatsächlich ein Problem.

Sie können jedoch auch / bin / bash verwenden, um das Problem vor und nach der Verzeichnisliste zu beheben

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
quelle
2
Warum /bin/bash -c 'chmod +x file'funktioniert und nicht /bin/sh -c 'chmod +x file'?
Sturm
Ihre ist bessere Lösung. es hat bei mir funktioniert. Vielen Dank .
user1427944
Die Verwendung des neuen Buildkits hilft auch in einer Reihe von Bereichen, einschließlich diesem. Versuche es. docs.docker.com/develop/develop-images/build_enhancements
Thad Guidry
4

Versuchen Sie hinzuzufügen:

USER root

Es hat bei mir funktioniert.

secavfr
quelle
Dies sollte die akzeptierte Antwort sein.
Vladimir Kornea
2
Wenn Sie zu root wechseln, sollten Sie wahrscheinlich zum vorherigen Benutzer zurückkehren, wenn Sie fertig sind oder wenn Sie die Sicherheit und Kompatibilität des Containers verringern. Einige Kubernetes-Implementierungen führen beispielsweise standardmäßig keinen Container als Root aus.
Flickerfly
2

Dieses Problem ist wahrscheinlich das Ergebnis einer VOLUMEDefinition in der vorgelagerten Docker-Datei. Wenn in der Docker-Datei ein Volume definiert ist, können Sie Dateien mit dem Befehl COPYoder ADDdirekt zum Image hinzufügen . Eine RUNZeile wird jedoch:

  • Erstellen Sie einen temporären Container mit der Bilddefinition ab dem aktuellen Punkt der Docker-Datei
    • In diesem temporären Container wird ein anonymes Volume als Sie oder ein in der Docker-Datei angegebenes übergeordnetes Image bereitgestellt
    • Das anonyme Volume wird aus dem Inhalt des Bildes initialisiert
  • Ihr Befehl wird im Container ausgeführt
    • Wenn Sie das Verzeichnis während dieses RUNBefehls auflisten, werden Ihre Änderungen angewendet, aber diese Änderungen wurden auf das Volume angewendet
  • Wenn Ihr Ausführungsbefehl abgeschlossen ist, erfasst Docker die Änderungen am Container
    • Diese Änderungen werden mit a docker diffangezeigt, wenn Sie die temporären Container nicht löschen (Sie können einen Build mit ausführen --rm=false, damit sie erhalten bleiben).
    • Diese Änderungen enthalten nicht den anonymen Datenträgerinhalt, da sie nicht im temporären Container-Dateisystem vorhanden sind. Die Datenträger sind separat

Aufgrund dieses Verhaltens haben Sie folgende Möglichkeiten:

  1. Sie können Ihre Dateien in ein anderes Verzeichnis kopieren und dort die Berechtigungen ändern
  2. Sie können die Berechtigungen auf Ihrem Host so festlegen, dass sie direkt mit diesen Berechtigungen kopiert werden
  3. Sie können das Volume entweder aus Ihrem Image entfernen, das Upstream-Image dazu bringen, die Volume-Definition zu entfernen, oder Sie können Ihre eigene Kopie des Upstream-Images ohne die Volume-Definition neu erstellen und Ihre Images darauf aufbauen

Beachten Sie, dass in den aktuellen PHP-Bildern das Volume anscheinend entfernt wurde, was bedeutet, dass wir effektiv Option 3 haben.

BMitch
quelle
0

Ich habe gerade ein Experiment mit folgendem gemacht:

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

Und es funktioniert einfach großartig.

jedoch

Wenn ich diese ausführbare Datei über Docker-Compose-Volumes überschreibe, ist die executeBerechtigung einfach wie ein Rollback - technisch überschrieben mit der ursprünglichen Dateiberechtigung.

Die Korrektur für den Dev-Modus erfolgt einfach chmod a+x yourfilevom Host, der bei der Erstellung des Compose-Volumes vererbt wird.

Salathiel Genèse
quelle
1
Das gesamte Ziel eines Volumes besteht darin, Dateien von einem anderen Ort als dem Image zu mounten. Wenn Sie also Ihr Image reparieren und ein Volume darüber mounten, werden Ihre Image-Änderungen aufgrund des Designs nicht angezeigt. Je nachdem, warum Sie ein Volume haben, besteht die Antwort möglicherweise darin, einfach kein Volume zu haben.
BMitch
Ja, BMitch , ich stimme voll und ganz dem Effekt des Mountens von Volumes zu, die Container-Fs aus Docker-Images überschreiben, aber ... Während der Entwicklung möchten Sie Ihren Container sicherlich nicht neu erstellen / neu starten, um jede einzelne Änderung zu testen tun. In diesem letzteren Szenario möchten Sie, dass ein Volume bereitgestellt wird, das vom Docker erstellte Image-Fs überschreibt. Und ich hatte das gleiche Problem, bevor ich hier landete. Ich wurde durch keine der beiden Antworterklärungen verurteilt und habe jeden von ihnen getestet. Erst dann verstand ich, was los war und veröffentlichte meine Beobachtungen ...
Salathiel Genèse
... und ich vermute, dass das Szenario, das ich erlebt habe, dasselbe ist wie das desjenigen, der die Frage gestellt hat.
Salathiel Genèse
Das OP gab an, dass das Problem nur mit einem docker runBefehl und ohne externe Volume-Bereitstellungen aufgetreten ist.
BMitch
Oups - Ich habe diesen Aspekt verpasst ... Die richtige Antwort für den richtigen Fragentitel, aber nicht das beschriebene Szenario. Dann darf ich erwähnen, dass ich das oben erwähnte Problem nicht reproduzieren konnte.
Salathiel Genèse