wake-up-neo.com

Docker - Befehl ausführen, nachdem ein Volume gemountet wurde

Ich habe die folgende Dockerfile für eine PHP-Laufzeit, die auf dem offiziellen [php][1]-Image basiert.

FROM php:fpm
WORKDIR /var/www/root/
RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libpng12-dev \
        Zip \
        unzip \
    && docker-php-ext-install -j$(nproc) iconv mcrypt \
    && docker-php-ext-configure Gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) Gd \
    && docker-php-ext-install mysqli \
    && docker-php-ext-enable opcache \
    && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
    && php -r "if (hash_file('SHA384', 'composer-setup.php') === '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
    && php composer-setup.php \
    && php -r "unlink('composer-setup.php');" \
    && mv composer.phar /usr/local/bin/composer

Ich habe Probleme beim Ausführen von composer install.

Ich vermute, dass die Docker-Datei ausgeführt wird, bevor ein Volume angehängt wird, weil ich eine Fehlermeldung composer.json-Datei nicht gefunden habe, wenn Sie Folgendes hinzufügen:

...
&& mv composer.phar /usr/local/bin/composer \
&& composer install

zu dem darüber.

Fügen Sie jedoch die folgende Eigenschaft zu docker-compose.yml hinzu:

command: sh -c "composer install && composer require drush/drush"

scheint den Container zu beenden, nachdem der Befehl ausgeführt wurde.

Gibt es einen Weg zu:

  • warten Sie, bis ein Volume bereitgestellt wird
  • führen Sie composer install mit der eingebundenen composer.json-Datei aus
  • lassen Sie den Behälter nachlaufen

?

7

Ich stimme der Antwort von Chris für lokale Entwicklung im Allgemeinen zu. Ich werde etwas anbieten, das mit einer aktuellen Docker-Funktion kombiniert wird, die einen Pfad für lokale Entwicklung und eventuelle Produktionsbereitstellung mit demselben Image festlegen kann.

Beginnen wir mit dem Image, das wir auf eine Art und Weise erstellen können, die entweder für die lokale Entwicklung oder für die Bereitstellung irgendwo verwendet werden kann, die Code und Abhängigkeiten enthält. In der neuesten Docker-Version (17.05) gibt es eine neue mehrstufige Build-Funktion, die wir nutzen können. In diesem Fall können wir zunächst alle Ihre Composer-Abhängigkeiten in einem Ordner im Build-Kontext installieren und später in das endgültige Abbild kopieren, ohne Composer zum endgültigen Abbild hinzufügen zu müssen. Das könnte so aussehen:

FROM composer as composer
COPY . /app
RUN composer install --ignore-platform-reqs --no-scripts

FROM php:fpm
WORKDIR /var/www/root/
RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libpng12-dev \
        Zip \
        unzip \
    && docker-php-ext-install -j$(nproc) iconv mcrypt \
    && docker-php-ext-configure Gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) Gd \
    && docker-php-ext-install mysqli \
    && docker-php-ext-enable opcache
COPY . /var/www/root
COPY --from=composer /app/vendor /var/www/root/vendor

Dadurch wird der gesamte Composer aus dem Anwendungsabbild selbst entfernt. Stattdessen werden im ersten Schritt die Abhängigkeiten in einem anderen Kontext installiert und in das endgültige Abbild kopiert.

Jetzt haben Sie während der Entwicklung einige Optionen. Basierend auf Ihrem docker-compose.yml-Befehl klingt es so, als würden Sie die Anwendung als .:/var/www/root in den Container einhängen. Sie könnten einen composer-Dienst zu Ihrem docker-compose.yml hinzufügen, der meinem Beispiel ähnlich ist: https://Gist.github.com/andyshinn/e2c428f2cd234b718239 . Hier müssen Sie nur docker-compose run --rm composer install tun, wenn Sie die Abhängigkeiten lokal aktualisieren müssen (dadurch bleiben die Abhängigkeiten im Container erhalten, was für native kompilierte Erweiterungen von Bedeutung sein kann, insbesondere wenn Sie als Container bereitstellen und auf Windows oder Mac entwickeln).

Die andere Option ist, einfach etwas zu tun, was Chris bereits vorgeschlagen hat, und das offizielle Composer-Image zum Aktualisieren und Verwalten von Abhängigkeiten zu verwenden, wenn dies erforderlich ist. Ich habe so etwas vor Ort gemacht, wo ich private Abhängigkeiten von GitHub hatte, für die SSH-Authentifizierung erforderlich war:

docker run --rm --interactive --tty --volume $PWD:/app:rw,cached --volume $SSH_AUTH_SOCK:/ssh-auth.sock --env SSH_AUTH_SOCK=/ssh-auth.sock --volume $COMPOSER_HOME:/composer composer:1.4 install --ignore-platform-reqs --no-scripts

Um es noch einmal zusammenzufassen, die Gründe für diese Methode zum Erstellen des Images und zum Installieren von Composer-Abhängigkeiten mithilfe eines externen Containers/Services:

  • Plattformspezifische Abhängigkeiten werden für den Container (Linux-Architektur vs. Windows oder Mac) korrekt erstellt.
  • Auf Ihrem lokalen Computer ist kein Composer oder PHP erforderlich (alles ist in Docker und Docker Compose enthalten).
  • Das ursprüngliche Image, das Sie erstellt haben, ist lauffähig und kann bereitgestellt werden, ohne dass Code darin eingebunden werden muss. In der Entwicklung überschreiben Sie einfach den /var/www/root-Ordner mit einem lokalen Volume.
5
Andy Shinn

Ich bin seit 5 Stunden in diesem Kaninchenbau, alle Lösungen sind viel zu kompliziert. Die einfachste Lösung besteht darin, Anbieter- oder Knotenmodule und ähnliche Verzeichnisse von Volume auszuschließen.

#docker-compose.yml
volumes:
      - .:/srv/app/
      - /srv/app/vendor/

Dadurch wird das aktuelle Projektverzeichnis zugeordnet, jedoch das Herstellerverzeichnis ausgeschlossen. Vergiss nicht den nachstehenden Schrägstrich!

Jetzt können Sie die Composer-Installation einfach in der Docker-Datei ausführen. Wenn das Docking-Volume Ihr Volume einbindet, wird das Herstellerverzeichnis ignoriert.

1
Buksy

Wenn es sich um eine allgemeine Entwicklungsumgebung handelt, ist die Intention nicht ideal, da die Anwendung mit der Docker-Konfiguration gekoppelt wird.

Führen Sie einfach composer install auf andere Weise getrennt aus (auf dem Dockerhub ist hierfür ein Bild verfügbar, mit dem Sie einfach (docker run -it --rm -v $(pwd):/app composer/composer install ausführen können).


Aber ja, es ist möglich, dass Sie die letzte Zeile in der Dockerfile als bash -c "composer install && php-fpm" verwenden müssen.


  • warten Sie, bis ein Volume bereitgestellt wird

Nein, Volumes können nicht während eines Docker-Build-Prozesses gemountet werden. Sie können den Quellcode jedoch in kopieren.

  • führen Sie die Composer-Installation mithilfe der eingebundenen Datei composer.json aus

Nein, siehe obige Antwort.

  • lass den Container weiterlaufen

Ja, Sie müssten php-fpm --nodaemonize ausführen (was ein langwieriger Prozess ist und daher nicht beendet wird.).

1