One place for hosting & domains

      Ausführen

      Verwenden eines Unterprozesses zum Ausführen externer Programme in Python 3


      Der Autor hat den COVID-19 Relief Fund dazu ausgewählt, eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      Python 3 beinhaltet das subprocess-Modul zum Ausführen externer Programme und Lesen ihrer Ausgaben in Ihrem Python-Code.

      Möglicherweise finden Sie subprocess nützlich, wenn Sie in Ihrem Python-Code auf Ihrem Computer ein anderes Programm verwenden möchten. Beispielsweise möchten Sie vielleicht git aus Ihrem Python-Code aufrufen, um Dateien in Ihrem Projekt abzurufen, die in der git-Versionskontrolle verfolgt werden. Da sich jedes Programm, das Sie auf Ihrem Computer aufrufen können, über subprocess steuern lässt, gelten die hier angegebenen Beispiele für externe Programme, die Sie ggf. über Ihren Python-Code aufrufen möchten.

      subprocess enthält verschiedene Klassen und Funktionen; wir werden in diesem Tutorial jedoch eine der nützlichsten Funktionen von subprocess abdecken: subprocess.run. Wir werden uns die verschiedenen Einsatzmöglichkeiten und wichtigsten Schlüsselwortargumente ansehen.

      Voraussetzungen

      Um das Beste aus diesem Tutorial herauszuholen, empfiehlt es sich, eine gewisse Vertrautheit mit Programmierung in Python 3 aufzuweisen. Sie können sich für die erforderlichen Hintergrundinformationen folgende Tutorials ansehen:

      Ausführen eines externen Programms

      Sie können mit der Funktion subprocess.run ein externes Programm über Ihren Python-Code ausführen. Zuerst müssen Sie jedoch die Module subprocess und sys in Ihr Programm importieren:

      import subprocess
      import sys
      
      result = subprocess.run([sys.executable, "-c", "print('ocean')"])
      

      Wenn Sie dies ausführen, erhalten Sie eine Ausgabe wie die folgende:

      Output

      ocean

      Sehen wir uns dieses Beispiel an:

      • sys.executable ist der absolute Pfad zur ausführbaren Python-Datei, mit der Ihr Programm ursprünglich aufgerufen wurde. Beispielsweise kann sys.executable ein Pfad wie /usr/local/bin/python sein.
      • An subprocess.run wird eine Liste mit Zeichenfolgen übergeben, die aus den Komponenten des Befehls besteht, den wir ausführen möchten. Da die erste Zeichenfolge, die wir übergeben, sys.executable ist, weisen wir subprocess.run an, ein neues Python-Programm auszuführen.
      • Die Komponente -c ist eine python-Befehlszeilenoption, mit der Sie eine Zeichenfolge mit einem gesamten Python-Programm zur Ausführung übergeben können. In unserem Fall übergeben wir ein Programm, das die Zeichenkette ocean ausgibt.

      Sie können sich jeden Eintrag in der Liste, den wir an subprocess.run übergeben, als durch ein Leerzeichen getrennt vorstellen. Beispielsweise wird [sys.executable, "-c", "print('ocean')"] in etwa zu /usr/local/bin/python -c "print('ocean')". Beachten Sie, dass subprocess automatisch die Komponenten des Befehls angibt, bevor versucht wird, sie im zugrunde liegenden Betriebssystem auszuführen. So können Sie beispielsweise einen Dateinamen übergeben, der Leerzeichen enthält.

      Warnung: Übergeben Sie nie unvertrauenswürdige Eingaben an subprocess.run. Da subprocess.run die Fähigkeit hat, beliebige Befehle auf Ihrem Computer auszuführen, können bösartige Akteure damit Ihren Computer auf unerwartete Weise manipulieren.

      Erfassen von Ausgaben aus einem externen Programm

      Nachdem wir mit subprocess.run ein externes Programm aufrufen können, sehen wir uns nun an, wie wir Ausgaben von diesem Programm erfassen können. Beispielsweise kann dieser Prozess nützlich sein, wenn wir git ls-files verwenden möchten, um alle aktuell in der Versionskontrolle gespeicherten Dateien auszugeben.

      Anmerkung: Die in diesem Abschnitt angegebenen Beispiele benötigen Python 3.7 oder höher. Insbesondere wurden die Schlüsselwortargumente capture_output und text in Python 3.7 hinzugefügt, als es im Juni 2018 veröffentlicht wurde.

      Ergänzen wir unser vorheriges Beispiel:

      import subprocess
      import sys
      
      result = subprocess.run(
          [sys.executable, "-c", "print('ocean')"], capture_output=True, text=True
      )
      print("stdout:", result.stdout)
      print("stderr:", result.stderr)
      

      Wenn wir diesen Code ausführen, erhalten wir eine Ausgabe wie die folgende:

      Output

      stdout: ocean stderr:

      Dieses Beispiel ist weitgehend das gleiche wie das im ersten Abschnitt eingeführte: Wir führen noch immer einen Unterprozess zum Ausdrucken von ocean aus. Wichtig:Wir übergeben jedoch die Schlüsselwortargumente capture_output=True und text=True an subprocess.run.

      subprocess.run gibt ein subprocess.CompletedProcess-Objekt zurück, das an result gebunden ist. Das Objekt subprocess.CompletedProcess enthält Details zum Exitcode des externen Programms und seiner Ausgabe. capture_output=True sorgt dafür, dass result.stdout und result.stderr mit der entsprechenden Ausgabe aus dem externen Programm gefüllt werden. Standardmäßig sind result.stdout und result.stderr als Bytes gebunden; das Schlüsselwortargument text=True weist Python an, die Bytes in Zeichenfolgen zu decodieren.

      Im Ausgabebereich lautet stdout ocean (plus der nachfolgenden neuen Zeile, die print implizit hinzufügt); wir verfügen über kein stderr.

      Versuchen wir es mit einem Beispiel, das für stderr einen nicht leeren Wert erstellt:

      import subprocess
      import sys
      
      result = subprocess.run(
          [sys.executable, "-c", "raise ValueError('oops')"], capture_output=True, text=True
      )
      print("stdout:", result.stdout)
      print("stderr:", result.stderr)
      

      Wenn wir diesen Code ausführen, erhalten wir eine Ausgabe wie die folgende:

      Output

      stdout: stderr: Traceback (most recent call last): File "<string>", line 1, in <module> ValueError: oops

      Dieser Code führt einen Python-Unterprozess aus, der sofort einen ValueError auslöst. Wenn wir das endgültige Ergebnis prüfen, sehen wir in stdout nichts und ein Traceback unseres ValueError in stderr. Das liegt daran, dass Python das Traceback der nicht behandelten Ausnahme in stderr schreibt.

      Auslösen einer Ausnahme bei einem fehlerhaften Exitcode

      Manchmal ist es nützlich, eine Ausnahme auszulösen, wenn ein ausgeführtes Programm mit einem fehlerhaften Exitcode beendet wird. Programme, die mit einem Nullcode beendet werden, werden als erfolgreich betrachtet; Programme, die mit einem Nicht-Nullcode beendet werden, werden hingegen als fehlerhaft betrachtet. Als Beispiel kann dieses Muster nützlich sein, wenn wir eine Ausnahme auslösen möchten für den Fall, dass wir git ls-files in einem Verzeichnis ausführen, das in Wahrheit kein git-Repository ist.

      Wir können das Schlüsselwortargument check=True nutzen, damit für subprocess.run eine Ausnahme ausgelöst wird, wenn das externe Programm einen Nicht-Null-Exitcode zurückgibt:

      import subprocess
      import sys
      
      result = subprocess.run([sys.executable, "-c", "raise ValueError('oops')"], check=True)
      

      Wenn wir diesen Code ausführen, erhalten wir eine Ausgabe wie die folgende:

      Output

      Traceback (most recent call last): File "<string>", line 1, in <module> ValueError: oops Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.8/subprocess.py", line 512, in run raise CalledProcessError(retcode, process.args, subprocess.CalledProcessError: Command '['/usr/local/bin/python', '-c', "raise ValueError('oops')"]' returned non-zero exit status 1.

      Diese Ausgabe zeigt, dass wir einen Unterprozess ausgeführt haben, der einen Fehler ausgelöst hat, der in unserem Terminal in stderr ausgegeben wird. Dann hat subprocess.run in unserem Namen in unserem zentralen Python-Programm ordnungsgemäß einen subprocess.CalledProcessError ausgelöst.

      Alternativ enthält das subprocess-Modul auch die Methode subprocess.CompletedProcess.check_returncode, die wir mit ähnlicher Wirkung aufrufen können:

      import subprocess
      import sys
      
      result = subprocess.run([sys.executable, "-c", "raise ValueError('oops')"])
      result.check_returncode()
      

      Wenn wir diesen Code ausführen, erhalten wir:

      Output

      Traceback (most recent call last): File "<string>", line 1, in <module> ValueError: oops Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.8/subprocess.py", line 444, in check_returncode raise CalledProcessError(self.returncode, self.args, self.stdout, subprocess.CalledProcessError: Command '['/usr/local/bin/python', '-c', "raise ValueError('oops')"]' returned non-zero exit status 1.

      Da wir check=True nicht an subprocess.run übergeben haben, haben wir eine subprocess.CompletedProcess-Instanz erfolgreich an result gebunden, obwohl unser Programm mit einem Nicht-Nullcode beendet wurde. Ein Aufruf von result.check_returncode() löst jedoch einen subprocess.CalledProcessError aus, da erkannt wird, dass der abgeschlossene Prozess mit einem fehlerhaften Code beendet wurde.

      Verwenden von Timeouts zum frühzeitigen Beenden von Programmen

      subprocess.run enthält das timeout-Argument, sodass Sie ein externes Programm anhalten können, wenn dessen Ausführung zu lange dauert:

      import subprocess
      import sys
      
      result = subprocess.run([sys.executable, "-c", "import time; time.sleep(2)"], timeout=1)
      

      Wenn wir diesen Code ausführen, erhalten wir eine Ausgabe wie die folgende:

      Output

      Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.8/subprocess.py", line 491, in run stdout, stderr = process.communicate(input, timeout=timeout) File "/usr/local/lib/python3.8/subprocess.py", line 1024, in communicate stdout, stderr = self._communicate(input, endtime, timeout) File "/usr/local/lib/python3.8/subprocess.py", line 1892, in _communicate self.wait(timeout=self._remaining_time(endtime)) File "/usr/local/lib/python3.8/subprocess.py", line 1079, in wait return self._wait(timeout=timeout) File "/usr/local/lib/python3.8/subprocess.py", line 1796, in _wait raise TimeoutExpired(self.args, timeout) subprocess.TimeoutExpired: Command '['/usr/local/bin/python', '-c', 'import time; time.sleep(2)']' timed out after 0.9997982999999522 seconds

      Der Unterprozess, den wir ausführen wollten, verwendet die Funktion time.sleep, um für 2 Sekunden zu schlafen. Wir haben jedoch das Schlüsselwortargument timeout=1 an subprocess.run übergeben, um bei unserem Unterprozess nach 1 Sekunde für ein Timeout zu sorgen. Das erklärt, warum unser Aufruf an subprocess.run letztlich eine subprocess.TimeoutExpired-Ausnahme ausgelöst hat.

      Beachten Sie, dass das Schlüsselwortargument timeout für subprocess.run ungefähr ist. Python wird sich bemühen, den Unterprozess nach der timeout-Zahl von Sekunden zu beenden; der Vorgang wird jedoch nicht unbedingt genau sein.

      Übergeben von Eingaben an Programme

      Manchmal erwarten Programme, dass Eingaben über stdin an sie übergeben werden.

      Das Schlüsselwortargument input an subprocess.run ermöglicht Ihnen, Daten an stdin des Unterprozesses zu übergeben. Beispiel:

      import subprocess
      import sys
      
      result = subprocess.run(
          [sys.executable, "-c", "import sys; print(sys.stdin.read())"], input=b"underwater"
      )
      

      Nach Ausführung dieses Codes erhalten wir eine Ausgabe wie die folgende:

      Output

      underwater

      In diesem Fall haben wir die Bytes underwater an input übergeben. Unser Zielunterprozess hat sys.stdin verwendet, um das übergebene stdin (underwater) zu lesen und in unserer Ausgabe auszugeben.

      Das Schlüsselwortargument input kann nützlich sein, wenn Sie mehrere subprocess.run-Aufrufe verketten möchten, um die Ausgabe eines Programms als Eingabe an ein anderes zu übergeben.

      Zusammenfassung

      Das subprocess-Modul ist ein leistungsfähiger Bestandeil der Python-Standardbibliothek, mit dem Sie externe Programme ausführen und deren Ausgaben bequem überprüfen können. In diesem Tutorial haben Sie gelernt, wie Sie subprocess.run verwenden können, um externe Programme zu steuern, Eingaben an sie zu übergeben, ihre Ausgabe zu analysieren und ihre Rückgabecodes zu überprüfen.

      Das subprocess-Modul macht zusätzliche Klassen und Dienstprogramme verfügbar, auf die wir in diesem Tutorial nicht eingegangen sind. Nachdem Sie nun über Grundkenntnisse verfügen, können Sie die Dokumentation des subprocess-Moduls nutzen, um mehr über andere verfügbare Klassen und Dienstprogramme zu erfahren.



      Source link

      Ausführen mehrerer PHP-Versionen auf einem Server mit Apache und PHP-FPM unter CentOS 7


      Der Autor hat den COVID-19 Relief Fund dazu ausgewählt, eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      Der Apache-Webserver verwendet virtuelle Hosts zur Verwaltung mehrerer Domänen auf einer einzigen Instanz. In ähnlicher Weise verwendet PHP-FPM einen Daemon, um mehrere PHP-Versionen auf einer einzigen Instanz zu verwalten. Zusammen können Sie Apache und PHP-FPM verwenden, um mehrere PHP-Webanwendungen zu hosten, von denen jede eine andere Version von PHP verwendet, alle auf dem gleichen Server und alle zur gleichen Zeit. Dies ist nützlich, da verschiedene Anwendungen möglicherweise verschiedene Versionen von PHP erfordern, aber einige Server-Stacks, wie ein herkömmlich konfigurierter LAMP-Stack, nur einen verwalten können. Die Kombination von Apache mit PHP-FPM ist auch eine kosteneffizientere Lösung als das Hosting jeder Anwendung auf ihrer eigenen Instanz.

      PHP-FPM bietet auch Konfigurationsoptionen für stderr– und stdout-Protokollierung, Notfall-Neustarts und adaptives Prozess-Spawning, was bei stark ausgelasteten Sites nützlich ist. Tatsächlich ist der Einsatz von Apache mit PHP-FPM einer der besten Stacks für das Hosting von PHP-Anwendungen, insbesondere, wenn es um die Leistung geht.

      In diesem Tutorial richten Sie zwei PHP-Sites auf einer einzigen Instanz ein. Jede Site verwendet ihre eigene Domäne und jede Domäne stellt ihre eigene PHP-Version bereit. Die erste, site1.your_domain, stellt PHP 7.0 bereit. Die zweite, site2.your_domain, stellt PHP 7.2 bereit.

      Voraussetzungen

      Schritt 1 – Installieren von PHP Versionen 7.0 und 7.2 mit PHP-FPM

      Wenn die Vorkehrungen abgeschlossen sind, können Sie jetzt die PHP-Versionen 7.0 und 7.2 installieren. Das SCL (Software Collections)-Repository verwaltet zahlreiche Versionen des PHP-Stacks für das CentOS 7-System. Wenn Sie die neueste Version von PHP benötigen und diese nicht auf SCL verfügbar ist, sehen Sie stattdessen im remi PPA (persönliches Paketarchiv) nach.

      Beginnen Sie mit der Installation des SCL Repository in Ihrem System:

      • sudo yum install centos-release-scl -y

      Wir wollen uns zunächst ansehen, welche PHP 7-Versionen auf SCL verfügbar sind:

      • sudo yum list rh-php7[0-9].x86_64

      Sie sehen eine Ausgabe wie diese:

      Output

      Available Packages rh-php70.x86_64 2.3-1.el7 centos-sclo-rh rh-php71.x86_64 1-1.el7 centos-sclo-rh rh-php72.x86_64 1-2.el7 centos-sclo-rh rh-php73.x86_64 1-1.el7 centos-sclo-rh

      Sie sehen, dass die neueste Version, PHP 7.3, auch verfügbar ist. Für unsere Beispiele werden wir jedoch die Versionen 7.0 und 7.2 installieren.

      Beginnen wir mit der älteren Version. Installieren Sie rh-php70 und rh-php70-php-fpm:

      • sudo yum install rh-php70 rh-php70-php-fpm -y
      • rh-php70 ist ein Metapaket, das PHP-Anwendungen ausführt.
      • rh-php7.0-php-fpm bietet den Fast Process Manager-Interpreter, der als Daemon ausgeführt wird und Fast/CGI-Anfragen empfängt.

      Wiederholen Sie den Vorgang für PHP-Version 7.2. Installieren Sie rh-php72 und rh-php72-php-fpm.

      • sudo yum install rh-php72 rh-php72-php-fpm -y

      Führen Sie als Nächstes die folgenden Befehle aus, um mit der Verwendung der beiden Software-Sammlungen zu beginnen:

      • sudo scl enable rh-php70 bash
      • sudo scl enable rh-php72 bash

      Standardmäßig hören beide PHP-Versionen Port 9000 ab. In diesem Tutorial möchten wir jedoch zwei Versionen gleichzeitig ausführen. Wir benennen daher zwei neue Ports:

      Dazu können Sie /etc/opt/rh/rh-php70/php-fpm.d/www.conf in einem beliebigen Texteditor öffnen und 9000 überall in 9002 ändern. Speichern und schließen Sie die Datei und wiederholen Sie den Vorgang für /etc/opt/rh/rh-php72/php-fpm.d/www.conf, aber ersetzen Sie jetzt 9000 durch 9003. Alternativ können Sie diese beiden sed-Befehle für die Ersetzungen verwenden:

      • sudo sed -i 's/:9000/:9002/' /etc/opt/rh/rh-php70/php-fpm.d/www.conf
      • sudo sed -i 's/:9000/:9003/' /etc/opt/rh/rh-php72/php-fpm.d/www.conf

      Sie haben nun einen eigenen Port für jeden Ihrer PHP Dienste angegeben. Bevor die Änderungen jedoch funktionieren, müssen Sie die Ports zu Ihrer SELinux Konfiguration hinzufügen.

      SELinux ist die Kurzform für Security Enhanced Linux und ist standardmäßig in CentOS 7 aktiviert. Damit Ihre Anwendungen ausgeführt werden können, müssen Sie die neuen Ports 9002 und 9003 Ihrer SELinux Datenbank hinzufügen und den httpd Diensten zuweisen. Verwenden Sie den Befehl semanage, um diese Aufgabe auszuführen:

      • sudo semanage port -a -t http_port_t -p tcp 9002
      • sudo semanage port -a -t http_port_t -p tcp 9003

      Das Flag -a gibt an, dass Sie der Datenbank ein Objekt hinzufügen. Das Flag -t gibt die Art des Objekts an. In diesem Fall handelt es sich um http_port_t. Flag -p ordnet das tcp-Protokoll zu. Sie können mehr über SELinux und den semanage-Befehl in diesem Tutorial oder durch einen Besuch der offiziellen SELinux-Dokumentation erfahren.

      Sie können nun die PHP Dienste starten und aktivieren. Beginnen Sie mit dem Dienst rh-php70-php-fpm und aktivieren Sie ihn zum Starten beim Booten:

      • sudo systemctl start rh-php70-php-fpm
      • sudo systemctl enable rh-php70-php-fpm

      Überprüfen Sie als Nächstes den Status des rh-php70-php-fpm-Dienstes:

      • sudo systemctl status rh-php70-php-fpm

      Sie sehen eine Ausgabe wie diese:

      Output

      ● rh-php70-php-fpm.service - The PHP FastCGI Process Manager Loaded: loaded (/usr/lib/systemd/system/rh-php70-php-fpm.service; enabled; vendor preset: disabled) Active: active (running) since Sat 2020-04-18 04:49:59 UTC; 1min 6s ago Main PID: 1852 (php-fpm) Status: "Processes active: 0, idle: 5, Requests: 0, slow: 0, Traffic: 0req/sec" CGroup: /system.slice/rh-php70-php-fpm.service ├─1852 php-fpm: master process (/etc/opt/rh/rh-php70/php-fpm.conf) ├─1853 php-fpm: pool www ├─1854 php-fpm: pool www ├─1855 php-fpm: pool www ├─1856 php-fpm: pool www └─1857 php-fpm: pool www Apr 18 04:49:59 centos-s-1vcpu-1gb-blr1-01 systemd[1]: Starting The PHP FastCGI Process Manager... Apr 18 04:49:59 centos-s-1vcpu-1gb-blr1-01 systemd[1]: Started The PHP FastCGI Process Manager.

      Wiederholen Sie den Vorgang, starten Sie den rh-php72-php-fpm-Dienst und aktivieren Sie ihn, sodass er beim Booten gestartet wird:

      • sudo systemctl start rh-php72-php-fpm
      • sudo systemctl enable rh-php72-php-fpm

      Überprüfen Sie als Nächstes den Status des rh-php70-php-fpm-Dienstes:

      • sudo systemctl status rh-php72-php-fpm

      Sie sehen eine Ausgabe wie diese:

      Output

      ● rh-php72-php-fpm.service - The PHP FastCGI Process Manager Loaded: loaded (/usr/lib/systemd/system/rh-php72-php-fpm.service; enabled; vendor preset: disabled) Active: active (running) since Sat 2020-04-18 04:50:04 UTC; 1min 59s ago Main PID: 1876 (php-fpm) Status: "Processes active: 0, idle: 5, Requests: 0, slow: 0, Traffic: 0req/sec" CGroup: /system.slice/rh-php72-php-fpm.service ├─1876 php-fpm: master process (/etc/opt/rh/rh-php72/php-fpm.conf) ├─1877 php-fpm: pool www ├─1878 php-fpm: pool www ├─1879 php-fpm: pool www ├─1880 php-fpm: pool www └─1881 php-fpm: pool www Apr 18 04:50:04 centos-s-1vcpu-1gb-blr1-01 systemd[1]: Starting The PHP FastCGI Process Manager... Apr 18 04:50:04 centos-s-1vcpu-1gb-blr1-01 systemd[1]: Started The PHP FastCGI Process Manager.

      Zu diesem Zeitpunkt haben Sie zwei PHP-Versionen auf Ihrem Server installiert. Als Nächstes erstellen Sie eine Verzeichnisstruktur für jede Website, die Sie bereitstellen möchten.

      Schritt 2 — Erstellen von Verzeichnisstrukturen für beide Websites

      In diesem Abschnitt erstellen Sie für beide Websites ein Dokumentenstammverzeichnis und eine Indexseite.

      Erstellen Sie zunächst Dokumentenstammverzeichnisse sowohl für site1.your_domain als auch für site2.your_domain:

      • sudo mkdir /var/www/site1.your_domain
      • sudo mkdir /var/www/site2.your_domain

      Der Apache-Webserver wird standardmäßig als apache-Benutzer und apache-Gruppe ausgeführt. So sollten /var/www/ und alle zugehörigen Dateien und Unterverzeichnisse ebenfalls unter deren Eigentümerschaft fallen. Führen Sie die folgenden Befehle aus, um die richtigen Eigentümerschaften und Berechtigungen der Website-Stammverzeichnisse zu überprüfen:

      • sudo chown -R apache:apache /var/www/site1.your_domain
      • sudo chown -R apache:apache /var/www/site2.your_domain
      • sudo chmod -R 755 /var/www/site1.your_domain
      • sudo chmod -R 755 /var/www/site2.your_domain

      Der Befehl chown ändert die Eigentümerschaften der beiden Website-Verzeichnisse auf den apache-Benutzer und die apache-Gruppe. Der Befehl chmod ändert die Berechtigungen, die mit diesem Benutzer und der Gruppe verknüpft sind, sowie mit anderen.

      Erstellen Sie als Nächstes in jedem Stammverzeichnis Ihrer Website eine Datei info.php. Dadurch werden die PHP-Versionsinformationen jeder Website angezeigt. Beginnen Sie mit site1:

      • sudo vi /var/www/site1.your_domain/info.php

      Fügen Sie die folgende Zeile hinzu:

      /var/www/site1.your_domain/info.php

      <?php phpinfo(); ?>
      

      Speichern und schließen Sie die Datei. Kopieren Sie nun die von Ihnen erstellte Datei info.php nach site2:

      • sudo cp /var/www/site1.your_domain/info.php /var/www/site2.your_domain/info.php

      Ihr Webserver sollte nun über die Stammverzeichnisse der Dokumente verfügen, die jede Site benötigt, um Besuchern Daten zur Verfügung zu stellen. Als Nächstes konfigurieren Sie Ihren Apache-Webserver, um mit zwei verschiedenen PHP-Versionen zu arbeiten.

      Schritt 3 – Konfigurieren von Apache für beide Websites

      In diesem Abschnitt erstellen Sie zwei Konfigurationsdateien für virtuelle Hosts. Dadurch können Ihre beiden Websites gleichzeitig mit zwei verschiedenen PHP-Versionen arbeiten.

      Damit Apache diesen Inhalt bereitstellen kann, ist es erforderlich, eine virtuelle Host-Datei mit den richtigen Anweisungen zu erstellen. Sie erstellen zwei neue virtuelle Host-Konfigurationsdateien im Verzeichnis /etc/httpd/conf.d/.

      Erstellen Sie zunächst eine neue Konfigurationsdatei für einen virtuellen Host für die Website site1.your_domain. Hier weisen Sie Apache an, Inhalte mit PHP 7.0 zu rendern:

      • sudo vi /etc/httpd/conf.d/site1.your_domain.conf

      Fügen Sie folgenden Inhalt hinzu: Stellen Sie sicher, dass der Website-Verzeichnispfad, der Servername, der Port und die PHP-Version mit Ihrer Einrichtung übereinstimmen:

      /etc/httpd/conf.d/site1.your_domain.conf

      
      <VirtualHost *:80>
           ServerAdmin admin@site1.your_domain
           ServerName site1.your_domain
           DocumentRoot /var/www/site1.your_domain
           DirectoryIndex info.php
           SetHandler "proxy:fcgi://127.0.0.1:9002
           ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
           AddHandler php70-fcgi .php
           Action php70-fcgi /cgi-bin/php70.fcgi
           ErrorLog /var/log/httpd/site1.your_domain_error.log
           CustomLog /var/log/httpd/site1.your_domain_access.log combined
      </VirtualHost>
      

      Für DocumentRoot geben Sie den Pfad Ihres Website-Stammverzeichnisses ein. Für ServerAdmin geben Sie eine E-Mail an, auf die der Administrator der Site your_domain zugreifen kann. Für ServerName fügen Sie die URL für Ihre erste Subdomäne hinzu. Für SetHandler geben Sie Port 9002 an. Die verbleibenden Anweisungen konfigurieren Ihren Dienst zudem für die Bereitstellung von PHP 7.0.

      Speichern und schließen Sie die Datei.

      Erstellen Sie als Nächstes eine neue virtuelle Host-Konfigurationsdatei für die Website site2.your_domain. Geben Sie diese Subdomäne für die Bereitstellung von PHP 7.2 an:

      • sudo vi /etc/httpd/conf.d/site2.your_domain.conf

      Fügen Sie folgenden Inhalt hinzu: Stellen Sie auch hier sicher, dass der Website-Verzeichnispfad, der Servername und die PHP-Version mit Ihren eindeutigen Informationen übereinstimmen:

      /etc/httpd/conf.d/site2.your_domain.conf

      <VirtualHost *:80>
           ServerAdmin admin@site2.your_domain
           ServerName site2.your_domain
           DocumentRoot /var/www/site2.your_domain
           DirectoryIndex info.php
           SetHandler "proxy:fcgi://127.0.0.1:9003
           ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
           AddHandler php72-fcgi .php
           Action php72-fcgi /cgi-bin/php72.fcgi
           ErrorLog /var/log/httpd/site2.your_domain_error.log
           CustomLog /var/log/httpd/site2.your_domain_access.log combined
      </VirtualHost>
      

      Wenn Sie fertig sind, speichern und schließen Sie die Datei. Überprüfen Sie anschließend die Apache-Konfigurationsdatei auf etwaige Syntaxfehler:

      • sudo apachectl configtest

      Sie sehen eine Ausgabe von Syntax OK:

      Output

      Starten Sie schließlich den Apache-Dienst neu, um Ihre Änderungen zu übernehmen:

      • sudo systemctl restart httpd

      Nachdem Sie Apache nun konfiguriert haben, um jede Site zu bedienen, werden Sie sie testen, um sicherzustellen, dass die richtigen PHP-Versionen ausgeführt werden.

      Schritt 4 – Testen beider Websites

      Zu diesem Zeitpunkt haben Sie zwei Websites konfiguriert, um zwei verschiedene PHP-Versionen auszuführen. Testen Sie nun die Ergebnisse.

      Öffnen Sie Ihren Webbrowser und besuchen Sie beide Sites http://site1.your_domain und http://site2.your_domain. Sie sehen zwei Seiten, die wie folgt aussehen:

      PHP 7.0 InfoseitePHP 7.2 Infoseite

      Beachten Sie die Titel. Die erste Seite zeigt an, dass site1.your_domain PHP-Version 7.0 bereitstellt. Die zweite zeigt an, dass site2.your_domain PHP-Version 7.2 bereitstellt.

      Nachdem Sie nun Ihre Sites getestet haben, entfernen Sie die Dateien info.php. Da sie sensible Informationen über Ihren Server enthalten und für unberechtigte Benutzer zugänglich sind, stellen sie ein Sicherheitsrisiko dar. Entfernen Sie die Dateien:

      • sudo rm -rf /var/www/site1.your_domain/info.php
      • sudo rm -rf /var/www/site2.your_domain/info.php

      Sie haben nun einen einzigen CentOS 7-Server, der zwei Websites mit zwei verschiedenen PHP-Versionen verwaltet. PHP-FPM ist jedoch nicht auf diese eine Anwendung beschränkt.

      Zusammenfassung

      Sie haben nun virtuelle Hosts und PHP-FPM kombiniert, um mehrere Websites und mehrere PHP-Versionen auf einem einzigen Server bereitzustellen. Die einzige praktische Beschränkung der Anzahl der PHP-Sites und PHP-Versionen, die Ihr Apache-Dienst verarbeiten kann, ist die Verarbeitungsleistung Ihrer Instanz.

      Von hier aus können Sie die fortgeschritteneren Funktionen von PHP-FPM erkunden, wie den adaptiven Spawning-Prozess oder die Protokollierung von sdtout und stderr. Oder Sie sichern jetzt Ihre Websites. Zu diesem Zweck können Sie unserem Tutorial zum Sichern Ihrer Sites mit kostenlosen TLS/SSL-Zertifikaten von Let’s Encrypt folgen.



      Source link

      Ausführen verschiedener PHP-Versionen auf einem Server unter Verwendung von Apache und PHP-FPM unter Debian 10


      Der Autor hat den COVID-19 Relief Fund dazu ausgewählt, eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      Der Apache-Webserver verwendet virtuelle Hosts zur Verwaltung mehrerer Domänen auf einer einzigen Instanz. In ähnlicher Weise verwendet PHP-FPM einen Daemon, um mehrere PHP-Versionen auf einer einzigen Instanz zu verwalten. Zusammen können Sie Apache und PHP-FPM verwenden, um mehrere PHP-Webanwendungen zu hosten, von denen jede eine andere Version von PHP verwendet, alle auf dem gleichen Server und alle zur gleichen Zeit. Dies ist nützlich, da verschiedene Anwendungen möglicherweise verschiedene Versionen von PHP erfordern, aber einige Server-Stacks, wie ein herkömmlich konfigurierter LAMP-Stack, nur einen verwalten können. Die Kombination von Apache mit PHP-FPM ist auch eine kosteneffizientere Lösung als das Hosting jeder Anwendung auf ihrer eigenen Instanz.

      PHP-FPM bietet auch Konfigurationsoptionen für stderr– und stdout-Protokollierung, Notfall-Neustarts und adaptives Prozess-Spawning, was bei stark ausgelasteten Sites nützlich ist. Tatsächlich ist der Einsatz von Apache mit PHP-FPM einer der besten Stacks für das Hosting von PHP-Anwendungen, insbesondere, wenn es um die Leistung geht.

      In diesem Tutorial richten Sie zwei PHP-Sites auf einer einzigen Instanz ein. Jede Site verwendet ihre eigene Domäne und jede Domäne stellt ihre eigene PHP-Version bereit. Die erste, site1.your_domain, stellt PHP 7.0 bereit. Die zweite, site2.your_domain, stellt PHP 7.2 bereit.

      Voraussetzungen

      Schritt 1 – Installieren von PHP Versionen 7.0 und 7.2 mit PHP-FPM

      Nachdem die Voraussetzungen erfüllt sind, installieren Sie nun PHP-Versionen 7.0 und 7.2 sowie PHP-FPM als auch mehrere zusätzliche Erweiterungen. Dazu müssen Sie jedoch zunächst das sury php-Repository zu Ihrem System hinzufügen.

      Installieren Sie zunächst mehrere erforderliche Pakete, einschließlich curl, wget und gnupg2:

      • sudo apt-get install curl wget gnupg2 ca-certificates lsb-release apt-transport-https -y

      Mit den obigen Paketen können Sie sicher auf das sury php-Repository zugreifen. sury php ist ein Drittanbieter-Repository oder PPA (Personal Package Archive). Es stellt PHP 7.4, 7.3, 7.2, 7.1 und 7.0 für das Debian-Betriebssystem bereit. Außerdem bietet es aktuellere Versionen von PHP als die offiziellen Debian 10-Repositorys und Sie können verschiedene Versionen von PHP im gleichen System installieren.

      Als Nächstes importieren Sie den Schlüssel des Pakets:

      • wget https://packages.sury.org/php/apt.gpg
      • sudo apt-key add apt.gpg

      Fügen Sie nun das Repository sury php Ihrem System hinzu:

      • echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php7.list

      Aktualisieren Sie das Repository:

      Installieren Sie als Nächstes php7.0, php7.0-fpm, php7.0-mysql, libapache2-mod-php7.0, und libapache2-mod-fcgid mit den folgenden Befehlen:

      • sudo apt-get install php7.0 php7.0-fpm php7.0-mysql libapache2-mod-php7.0 libapache2-mod-fcgid -y
      • php7.0 ist ein Metapaket zur Ausführung von PHP-Anwendungen.
      • php7.0-fpm bietet den Fast Process Manager-Interpreter, der als Daemon ausgeführt wird und Fast/CGI-Anfragen empfängt.
      • php7.0-mysql verbindet PHP mit der MySQL-Datenbank.
      • libapahce2-mod-php7.0 stellt das PHP-Modul für den Apache-Webserver bereit.
      • libapache2-mod-fcgid enthält eine mod_fcgid, die eine Reihe von CGI-Programminstanzen startet, um gleichzeitige Anfragen zu bearbeiten.

      Wiederholen Sie den Vorgang für PHP-Version 7.2. Installieren Sie php7.2, php7.2-fpm, php7.2-mysql und libapache2-mod-php7.2.

      • sudo apt-get install php7.2 php7.2-fpm php7.2-mysql libapache2-mod-php7.2 -y

      Starten Sie nach Installation beider PHP-Versionen den Dienst php7.0-fpm:

      • sudo systemctl start php7.0-fpm

      Überprüfen Sie als Nächstes den Status des php7.0-fpm-Dienstes:

      • sudo systemctl status php7.0-fpm

      Sie sehen die folgende Ausgabe:

      Output

      ● php7.0-fpm.service - The PHP 7.0 FastCGI Process Manager Loaded: loaded (/lib/systemd/system/php7.0-fpm.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2020-04-04 08:51:47 UTC; 1min 17s ago Docs: man:php-fpm7.0(8) Main PID: 13016 (php-fpm7.0) Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec" Tasks: 3 (limit: 1149) Memory: 19.1M CGroup: /system.slice/php7.0-fpm.service ├─13016 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf) ├─13017 php-fpm: pool www └─13018 php-fpm: pool www Apr 04 08:51:47 debian10 systemd[1]: Starting The PHP 7.0 FastCGI Process Manager... Apr 04 08:51:47 debian10 systemd[1]: Started The PHP 7.0 FastCGI Process Manager.

      Wiederholen Sie diesen Vorgang nun zum Starten des php7.2-fpm-Dienstes:

      • sudo systemctl start php7.2-fpm

      Und überprüfen Sie dann den Status des php7.2-fpm-Dienstes:

      • sudo systemctl status php7.2-fpm

      Sie sehen die folgende Ausgabe:

      Output

      ● php7.2-fpm.service - The PHP 7.2 FastCGI Process Manager Loaded: loaded (/lib/systemd/system/php7.2-fpm.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2020-04-04 08:52:52 UTC; 1min 32s ago Docs: man:php-fpm7.2(8) Process: 22207 ExecStartPost=/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/7.2/fpm/pool.d/www.conf 72 (code=exite Main PID: 22204 (php-fpm7.2) Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec" Tasks: 3 (limit: 1149) Memory: 12.0M CGroup: /system.slice/php7.2-fpm.service ├─22204 php-fpm: master process (/etc/php/7.2/fpm/php-fpm.conf) ├─22205 php-fpm: pool www └─22206 php-fpm: pool www Apr 04 08:52:52 debian10 systemd[1]: Starting The PHP 7.2 FastCGI Process Manager... Apr 04 08:52:52 debian10 systemd[1]: Started The PHP 7.2 FastCGI Process Manager.

      Abschließend müssen Sie mehrere Module aktivieren, damit Ihr Apache2-Dienst mit mehreren PHP-Versionen arbeiten kann:

      • sudo a2enmod actions fcgid alias proxy_fcgi
      • actions wird für die Ausführung von CGI-Skripten verwendet, die auf Medientyp oder Anfragemethode basieren.

      • fcgid ist eine hochleistungsfähige Alternative zu mod_cgi, die eine ausreichende Anzahl von Instanzen des CGI-Programms zur Bearbeitung simultaner Anfragen startet.

      • alias stellt die Abbildung verschiedener Teile des Host-Dateisystems im Dokumentenbaum bereit und dient der URL-Umleitung.

      • proxy_fcgi ermöglicht Apache die Weiterleitung von Anfragen an PHP-FPM.

      Starten Sie nun den Apache-Dienst neu, um Ihre Änderungen zu übernehmen:

      • sudo systemctl restart apache2

      Zu diesem Zeitpunkt haben Sie zwei PHP-Versionen auf Ihrem Server installiert. Als Nächstes erstellen Sie eine Verzeichnisstruktur für jede Website, die Sie bereitstellen möchten.

      Schritt 2 — Erstellen von Verzeichnisstrukturen für beide Websites

      In diesem Abschnitt erstellen Sie für beide Websites ein Dokumentenverzeichnis und eine Indexseite.

      Erstellen Sie zunächst Dokument-Stammverzeichnisse sowohl für site1.your_domain als auch für site2.your_domain:

      • sudo mkdir /var/www/site1.your_domain
      • sudo mkdir /var/www/site2.your_domain

      Standardmäßig wird der Apache-Webserver als Benutzer www-data und als Gruppe www-data ausgeführt. Um sicherzustellen, dass Sie über die korrekte Eigentümerschaften und Berechtigungen für die Stammverzeichnisse Ihrer Website verfügen, führen Sie die folgenden Befehle aus:

      • sudo chown -R www-data:www-data /var/www/site1.your_domain
      • sudo chown -R www-data:www-data /var/www/site2.your_domain
      • sudo chmod -R 755 /var/www/site1.your_domain
      • sudo chmod -R 755 /var/www/site2.your_domain

      Erstellen Sie als Nächstes in jedem Stammverzeichnis Ihrer Website eine Datei info.php. Dadurch werden die PHP-Version jeder Website angezeigt. Beginnen Sie mit site1:

      • sudo nano /var/www/site1.your_domain/info.php

      Fügen Sie die folgende Zeile hinzu:

      /var/www/site1.your_domain/info.php

      <?php phpinfo(); ?>
      

      Speichern und schließen Sie die Datei. Kopieren Sie nun die von Ihnen erstellte Datei info.php nach site2:

      • sudo cp /var/www/site1.your_domain/info.php /var/www/site2.your_domain/info.php

      Ihr Webserver sollte nun über die Stammverzeichnisse der Dokumente verfügen, die jede Site benötigt, um Besuchern Daten zur Verfügung zu stellen. Als Nächstes konfigurieren Sie Ihren Apache-Webserver, um mit zwei verschiedenen PHP-Versionen zu arbeiten.

      Schritt 3 – Konfigurieren von Apache für beide Websites

      In diesem Abschnitt erstellen Sie zwei Konfigurationsdateien für virtuelle Hosts. Dadurch können Ihre beiden Websites gleichzeitig mit zwei verschiedenen PHP-Versionen arbeiten.

      Damit Apache diesen Inhalt bereitstellen kann, ist es erforderlich, eine virtuelle Host-Datei mit den richtigen Anweisungen zu erstellen. Anstatt die Standardkonfigurationsdatei unter /etc/apache2/sites-available/000-default.conf zu ändern, erstellen Sie zwei neue in dem Verzeichnis /etc/apache2/sites-available.

      Erstellen Sie zunächst eine neue Konfigurationsdatei für einen virtuellen Host für die Website site1.your_domain. Hier weisen Sie Apache an, Inhalte mit php7.0 zu rendern:

      • sudo nano /etc/apache2/sites-available/site1.your_domain.conf

      Fügen Sie folgenden Inhalt hinzu: Stellen Sie sicher, dass der Website-Verzeichnispfad, der Servername und die PHP-Version mit Ihrer Einrichtung übereinstimmen:

      /etc/apache2/sites-available/site1.your_domain.conf

      
      <VirtualHost *:80>
           ServerAdmin admin@site1.your_domain
           ServerName site1.your_domain
           DocumentRoot /var/www/site1.your_domain
           DirectoryIndex info.php
      
           <Directory /var/www/site1.your_domain>
              Options Indexes FollowSymLinks MultiViews
              AllowOverride All
              Order allow,deny
              allow from all
           </Directory>
      
          <FilesMatch .php$>
            # For Apache version 2.4.10 and above, use SetHandler to run PHP as a fastCGI process server
            SetHandler "proxy:unix:/run/php/php7.0-fpm.sock|fcgi://localhost"
          </FilesMatch>
      
           ErrorLog ${APACHE_LOG_DIR}/site1.your_domain_error.log
           CustomLog ${APACHE_LOG_DIR}/site1.your_domain_access.log combined
      </VirtualHost>
      

      In dieser Datei haben Sie die DocumentRoot auf Ihr neues Verzeichnis und ServerAdmin auf eine E-Mail aktualisiert, auf die der Administrator der Website your_domain zugreifen kann. Weiterhin haben Sue ServerName aktualisiert, der die Basisdomäne für diese Konfiguration des virtuellen Hosts festlegt, und Sie haben eine Anweisung SetHandler hinzugefügt, um PHP als fastCGI-Prozessserver auszuführen.

      Speichern und schließen Sie die Datei.

      Erstellen Sie als Nächstes eine neue Konfigurationsdatei des virtuellen Hosts für die Website site2.your_domain. Sie geben diese Subdomäne für die Bereitstellung von php7.2 an:

      • sudo nano /etc/apache2/sites-available/site2.your_domain.conf

      Fügen Sie folgenden Inhalt hinzu: Stellen Sie auch hier sicher, dass der Website-Verzeichnispfad, der Servername und die PHP-Version mit Ihrer Einrichtung übereinstimmen:

      /etc/apache2/sites-available/site2.your_domain.conf

      <VirtualHost *:80>
           ServerAdmin admin@site2.your_domain
           ServerName site2.your_domain
           DocumentRoot /var/www/site2.your_domain
           DirectoryIndex info.php  
      
           <Directory /var/www/site2.your_domain>
              Options Indexes FollowSymLinks MultiViews
              AllowOverride All
              Order allow,deny
              allow from all
           </Directory>
      
          <FilesMatch .php$>
            # For Apache version 2.4.10 and above, use SetHandler to run PHP as a fastCGI process server
            SetHandler "proxy:unix:/run/php/php7.2-fpm.sock|fcgi://localhost"
          </FilesMatch>
      
           ErrorLog ${APACHE_LOG_DIR}/site2.your_domain_error.log
           CustomLog ${APACHE_LOG_DIR}/site2.your_domain_access.log combined
      </VirtualHost>
      

      Wenn Sie fertig sind, speichern und schließen Sie die Datei. Überprüfen Sie anschließend die Apache-Konfigurationsdatei auf etwaige Syntaxfehler:

      • sudo apachectl configtest

      Sie sehen die folgende Ausgabe:

      Output

      Syntax OK

      Aktivieren Sie dann beide Konfigurationsdateien des virtuellen Hosts:

      • sudo a2ensite site1.your_domain
      • sudo a2ensite site2.your_domain

      Deaktivieren Sie nun die Standardseite, da Sie sie nicht benötigen:

      • sudo a2dissite 000-default.conf

      Starten Sie schließlich den Apache-Dienst neu, um Ihre Änderungen zu übernehmen:

      • sudo systemctl restart apache2

      Nachdem Sie Apache nun konfiguriert haben, um jede Site zu bedienen, werden Sie sie testen, um sicherzustellen, dass die richtigen PHP-Versionen ausgeführt werden.

      Schritt 4 – Testen beider Websites

      Zu diesem Zeitpunkt haben Sie zwei Websites konfiguriert, um zwei verschiedene PHP-Versionen auszuführen. Testen Sie nun die Ergebnisse.

      Öffnen Sie Ihren Webbrowser und besuchen Sie beide Sites http://site1.your_domain und http://site2.your_domain. Sie sehen zwei Seiten, die wie folgt aussehen:

      PHP 7.0 InfoseitePHP 7.2 Infoseite

      Beachten Sie die Titel. Die erste Seite zeigt an, dass site1.your_domain PHP-Version 7.0 bereitstellt. Die zweite zeigt an, dass site2.your_domain PHP-Version 7.2 bereitstellt.

      Nachdem Sie nun Ihre Sites getestet haben, entfernen Sie die Dateien info.php. Da sie sensible Informationen über Ihren Server enthalten und für unberechtigte Benutzer zugänglich sind, stellen sie eine Sicherheitsbedrohung dar. Führen Sie zur Entfernung beider Dateien die folgenden Befehle aus:

      • sudo rm -rf /var/www/site1.your_domain/info.php
      • sudo rm -rf /var/www/site2.your_domain/info.php

      Jetzt verfügen Sie über einen einzelnen Debian 10-Server, der zwei Websites mit zwei verschiedenen PHP-Versionen handhabt. PHP-FPM ist jedoch nicht auf diese eine Anwendung beschränkt.

      Zusammenfassung

      Sie haben nun virtuelle Hosts und PHP-FPM kombiniert, um mehrere Websites und mehrere PHP-Versionen auf einem einzigen Server bereitzustellen. Die einzige praktische Beschränkung der Anzahl der PHP-Sites und PHP-Versionen, die Ihr Apache-Dienst verarbeiten kann, ist die Verarbeitungsleistung Ihrer Instanz.

      Von hier aus können Sie die fortgeschritteneren Funktionen von PHP-FPM erkunden, wie den adaptiven Spawning-Prozess oder wie sdtout und stderr protokolliert werden können. Alternativ können Sie jetzt auch Ihre Websites sichern. Zu diesem Zweck können Sie unserem Tutorial zum Sichern Ihrer Sites mit kostenlosen TLS/SSL-Zertifikaten von Let’s Encrypt folgen.



      Source link