One place for hosting & domains

      exécuter

      Comment utiliser le module subprocess pour exécuter des programmes externes en Python 3


      L’auteur a choisi le COVID-19 Relief Fund pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      Python 3 comprend le module subprocess permettant d’exécuter des programmes externes et de lire leurs sorties dans votre code Python.

      Il se peut que vous trouviez subprocess utile si vous voulez utiliser un autre programme sur votre ordinateur à partir de votre code Python. Par exemple, vous pouvez invoquer git depuis votre code Python pour récupérer les fichiers de votre projet qui sont suivis dans le contrôle de version de git. Comme tout programme auquel vous pouvez accéder sur votre ordinateur par subprocess, les exemples présentés ici s’appliquent à tout programme externe que vous pourriez vouloir invoquer à partir de votre code Python.

      subprocess comprend plusieurs classes et fonctions, mais dans ce tutoriel, nous couvrirons l’une des fonctions les plus utiles de subprocess : subprocess.run. Nous passerons en revue ses différentes utilisations et les principaux arguments des mots-clés.

      Conditions préalables

      Pour tirer le meilleur parti de ce tutoriel, il est recommandé d’être familiarisé avec la  programmation en Python 3. Vous pouvez consulter ces tutoriels pour obtenir les informations de base nécessaires :

      Exécution d’un programme externe

      Vous pouvez utiliser la fonction subprocess.run pour exécuter un programme externe à partir de votre code Python. Mais d’abord, vous devez importer les modules subprocess et sys dans votre programme :

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

      Si vous l’exécutez, vous obtiendrez une sortie comme ci-dessous :

      Output

      ocean

      Passons en revue cet exemple :

      • sys.executable est le chemin absolu vers l’exécutable Python avec lequel votre programme a été invoqué à l’origine. Par exemple, sys.executable pourrait être un chemin tel que /usr/local/bin/python.
      • subprocess.run reçoit une liste de chaînes de caractères comprenant les composants de la commande que nous essayons d’exécuter. Comme la première chaîne que nous passons est sys.executable, nous ordonnons à subprocess.run d’exécuter un nouveau programme Python.
      • Le composant -c est une option de ligne de commande python qui vous permet de passer une chaîne avec un programme Python entier à exécuter. Dans notre cas, nous passons un programme qui imprime la chaîne ocean.

      Vous pouvez penser que chaque entrée de la liste que nous passons à subprocess.run est séparée par un espace. Par exemple, [sys.executable, "-c", "print('ocean')"] se traduit approximativement par /usr/local/bin/python -c "print('ocean')". Notez que subprocess cite automatiquement les composants de la commande avant d’essayer de les exécuter sur le système d’exploitation sous-jacent de sorte que, par exemple, vous pouvez passer un nom de fichier qui contient des espaces.

      Warning : ne jamais transmettre une entrée non fiable à subprocess.run. Comme subprocess.run a la capacité d’exécuter des commandes arbitraires sur votre ordinateur, des acteurs malveillants peuvent l’utiliser pour manipuler votre ordinateur de manière inattendue.

      Capturer output d’un programme externe

      Maintenant que nous pouvons invoquer un programme externe en utilisant subprocess.run, voyons comment nous pouvons récupérer la sortie de ce programme. Par exemple, ce processus pourrait être utile si nous voulions utiliser git ls-files pour produire tous vos fichiers actuellement stockés sous contrôle de version.

      Note : Les exemples présentés dans cette section nécessitent Python 3.7 ou version supérieure. En particulier, les arguments capture_output et le mot-clé text ont été ajoutés à Python 3.7 lors de sa sortie en juin 2018.

      Ajoutons à notre exemple précédent :

      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)
      

      Si nous exécutons ce code, nous obtiendrons le résultat suivant :

      Output

      stdout: ocean stderr:

      Cet exemple est en grande partie le même que celui présenté dans la première section : nous sommes toujours en train d’exécuter un sous-processus pour imprimer ocean. Il est toutefois important de noter que nous passons les arguments des mots-clés capture_output=True et text=True à subprocess.run.

      subprocess.run renvoie un objet subprocess.CompletedProcess qui est lié à result. L’objet subprocess.CompletedProcess comprend des détails sur le code de sortie du programme externe et sa sortie. capture_output=True garantit que result.stdout et result.stderr sont remplis avec la sortie correspondante du programme externe. Par défaut, result.stdout et result.stderr sont liés en tant qu’octets, mais l’argument du mot-clé text=True indique à Python de décoder plutôt les octets en chaînes de caractères.

      Dans la section de sortie, stdout est ocean (plus la nouvelle ligne de fin que print ajoute implicitement), et nous n’avons pas de stderr.

      Essayons un exemple qui produit une valeur non vide pour stderr :

      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)
      

      Si nous exécutons ce code, nous obtenons une sortie comme celle qui suit :

      Output

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

      Ce code exécute un sous-processus Python qui génère immédiatement une ValueError. Lorsque nous inspectons le result final, nous ne voyons rien dans stdout et un Traceback de notre ValueError dans stderr. C’est parce que par défaut Python écrit le Traceback de l’exception non gérée à stderr .

      Lever une exception sur un code de sortie incorrect

      Il est parfois utile de lever une exception si un programme que nous exécutons sort avec un code de sortie incorrect. Les programmes qui sortent avec un code nul sont considérés comme réussis, mais les programmes qui sortent avec un code non-nul sont considérés comme ayant rencontré une erreur. Par exemple, ce modèle pourrait être utile si nous voulions lever une exception dans le cas où nous exécutons des fichiers git ls-files dans un répertoire qui n’est pas réellement un référentiel git.

      Nous pouvons utiliser l’argument check=True du mot-clé subprocess.run pour qu’une exception soit levée si le programme externe renvoie un code de sortie non-nul :

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

      Si nous exécutons ce code, nous obtenons une sortie comme celle qui suit :

      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.

      Cette sortie montre que nous avons exécuté un sous-processus qui a généré une erreur imprimée en stderr dans notre terminal. Ensuite, subprocess.run a consciencieusement levé un subprocess.CalledProcessError en notre nom dans notre programme Python principal.

      Alternativement, le module de sous-processus comprend également la méthode subprocess.CompletedProcess.check_returncode que nous pouvons invoquer pour un effet similaire :

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

      Si nous exécutons ce code, nous recevrons :

      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.

      Comme nous n’avons pas passé check=True à subprocess.run, nous avons lié avec succès une instance de subprocess.CompletedProcess à result, même si notre programme s’est terminé avec un code non nul. L’appel de result.check_returncode() fait cependant apparaître un sous-processus appelé CalledProcessError parce qu’il détecte le processus terminé sorti avec un code incorrect.

      Utilisation du délai d’attente pour quitter prématurément les programmes

      subprocess.run inclut l’argument timeout pour vous permettre d’arrêter un programme externe si son exécution est trop longue :

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

      Si nous exécutons ce code, nous obtiendrons le résultat suivant :

      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

      Le sous-processus que nous avons essayé d’exécuter utilisait la fonction time.sleep pour se mettre en veille pendant 2 secondes. Cependant, nous avons passé l’argument du mot-clé timeout=1 à subprocess.run pour que notre sous-processus soit temporisé après 1 seconde. Cela explique pourquoi notre appel à subprocess.run a finalement soulevé une exception de subprocess.TimeoutExpired.

      Notez que l’argument du mot-clé timeout à subprocess.run est approximatif. Python fera tout son possible pour arrêter le sous-processus après le nombre de secondes stipulé dans timeout, mais ce ne sera pas nécessairement exact.

      Transmission d’Input aux programmes

      Parfois, les programmes s’attendent à ce que les données leur soient transmises via stdin.

      L’argument du mot-clé input à subprocess.run vous permet de passer des données au stdin du sous-processus. Par exemple :

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

      Après l’exécution de ce code, nous recevrons une sortie comme celle qui suit :

      Output

      underwater

      Dans ce cas, nous avons passé les octets underwater à input. Notre sous-processus cible a utilisé sys.stdin pour lire le passage dans stdin ( underwater ) et l’a imprimé dans notre sortie.

      L’argument du mot-clé input peut être utile si vous voulez enchaîner plusieurs appels subprocess.run ensemble en passant la sortie d’un programme comme entrée à un autre.

      Conclusion

      Le module subprocess est une partie puissante de la bibliothèque standard Python, qui vous permet d’exécuter des programmes externes et d’inspecter leurs sorties facilement. Dans ce tutoriel, vous avez appris à utiliser subprocess.run pour contrôler des programmes externes, leur transmettre des entrées, analyser leurs sorties et vérifier leurs codes de retour.

      Le module subprocess propose des classes et des utilitaires supplémentaires que nous n’avons pas abordés dans ce tutoriel. Maintenant que vous disposez d’une base de référence, vous pouvez utiliser la documentation du module subprocess pour en savoir plus sur d’autres classes et utilitaires disponibles.



      Source link

      Comment exécuter plusieurs Versions PHP sur un serveur en utilisant Apache et PHP-FPM sur CentOS 7


      L’auteur a choisi le COVID-19 Relief Fund pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      Le serveur web Apache utilise des hôtes virtuels pour gérer plusieurs domaines sur une seule instance. De même, PHP-FPM utilise un démon pour gérer plusieurs versions PHP sur une seule instance. Vous pouvez utiliser ensemble Apache et PHP-FPM pour héberger plusieurs applications Web PHP, chacune utilisant une version différente de PHP, toutes sur le même serveur, et toutes en même temps. C’est utile car différentes applications peuvent nécessiter différentes versions de PHP, mais certaines piles de serveurs, telles qu’une pile LAMP régulièrement configurée, ne peuvent gérer qu’une seule version. Combiner Apache avec PHP-FPM est également une solution plus économique que d’héberger chaque application sur sa propre instance.

      PHP-FPM offre également des options de configuration pour la journalisation stderr et stdout, les redémarrages d’urgence et le lancement de processus adaptatifs, ce qui est utile pour les sites très chargés. En fait, l’utilisation d’Apache avec PHP-FPM est l’une des meilleures piles pour héberger des applications PHP, surtout en matière de performances.

      Dans ce tutoriel, vous allez configurer deux sites PHP sur une seule instance. Chaque site utilisera son propre domaine, et chaque domaine déploiera sa propre version de PHP. Le premier, site1.your_domain, déploiera PHP 7.0. La deuxième, site2.your_domain, déploiera PHP 7.2.

      Conditions préalables

      Étape 1 – Installation des Versions PHP 7.0 et 7.2 avec PHP-FPM

      Une fois les conditions préalables remplies, vous allez maintenant installer les versions PHP 7.0 et 7.2. Le référentiel SCL (Collections de logiciels) maintient de nombreuses versions de la pile PHP pour le système CentOS 7. Si vous avez besoin de la version la plus récente de PHP et qu’elle n’est pas disponible sur SCL, consultez plutôt le PPA (personal package archive) de remi.

      Commencez par installer le référentiel SCL sur votre système :

      • sudo yum install centos-release-scl -y

      Voyons d’abord quelles versions de PHP 7 sont disponibles sur SCL :

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

      Vous verrez une sortie de ce type :

      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

      Vous verrez que la version la plus récente, PHP 7.3, est également disponible. Pour nos exemples, nous allons toutefois installer les versions 7.0 et 7.2.

      Commençons par la version la plus ancienne. Installez rh-php70 et rh-php70-php-fpm :

      • sudo yum install rh-php70 rh-php70-php-fpm -y
      • rh-php70 est un metapackage qui exécute des applications PHP.
      • rh-php70-php-fpm fournit l’interpréteur Fast Process Manager qui fonctionne comme démon et reçoit des requêtes Fast/CGI.

      Repérez maintenant le processus pour la version PHP 7.2. Installez rh-php72 et rh-php72-php-fpm.

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

      Ensuite, exécutez les commandes suivantes pour commencer à utiliser les deux collections logicielles :

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

      Par défaut, les deux versions de PHP sont à l’écoute sur le port 9000. Mais dans ce tutoriel, nous voulons exécuter deux versions simultanément. Par conséquent, nous allons désigner deux nouveaux ports :

      Pour ce faire, vous pouvez ouvrir /etc/opt/rh/rh-php70/php-fpm.d/www.conf dans votre éditeur de texte préféré et changer chaque apparence de 9000 à 9002. Ensuite, enregistrez et fermez le fichier et répétez le processus pour /etc/opt/rh/rh-php72/php-fpm.d/www.conf, ne remplacez maintenant 9000 que par 9003. Vous pouvez en outre utiliser ces deux commandes sed pour faire les remplaçants :

      • 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

      Vous avez maintenant désigné un port dédié pour chacun de vos services PHP. Cependant, avant que ces modifications ne fonctionnent, vous devez ajouter les ports à votre configuration SELinux.

      CentOS 7. Vous devez ajouter vos nouveaux ports 9002 et 9003 à votre base de données SELinux et les attribuer à vos services httpd, sinon vos applications ne fonctionneront pas. Utilisez la commande semanage pour effectuer cette tâche :

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

      Le drapeau -a spécifie que vous ajoutez un objet à la base de données. Le drapeau -t spécifie le type d’objet, qui dans ce cas est http_port_t​​​. Et le drapeau -p désigne le protocole tcp. Vous pouvez en apprendre davantage sur SELinux et la commande semanage dans ce tutoriel, ou en consultant la documentation officielle SELinux.

      Maintenant, vous êtes prêt à démarrer et à activer vos services PHP. Commencez par votre service rh-php70-php-fpm et activez-le au démarrage :

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

      Ensuite, vérifiez l’état de votre service rh-php70-php-fpm

      • sudo systemctl status rh-php70-php-fpm

      Vous verrez une sortie de ce type :

      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.

      En répétant ce processus, démarrez le service rh-php72-php-fpm et activez-le au démarrage :

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

      Ensuite, vérifiez l’état de votre service rh-php72-php-fpm

      • sudo systemctl status rh-php72-php-fpm

      Vous verrez une autre sortie comme celle-ci :

      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.

      À ce stade, vous avez installé deux versions PHP sur votre serveur. Ensuite, vous allez créer une structure de répertoire pour chaque site web que vous voulez déployer.

      Étape 2 — Création de structures répertoire pour les deux sites Web

      Dans cette section, vous créerez un répertoire root de document et une page index pour chacun de vos deux sites Web.

      Tout d’abord, créez des répertoires root de documents à la fois pour site1.your_domain et site2.your_domain

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

      Par défaut, le serveur web Apache fonctionne comme un utilisateur apache et un groupe apache. Donc /var/www/ et tous ses fichiers et sous-répertoires devraient également leur appartenir. Exécutez les commandes suivantes pour vérifier la propriété et les autorisations correctes des répertoires racines de votre site web :

      • 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

      La commande chown change la propriété des deux répertoires de votre site web pour l’utilisateur apache et le groupe apache. La commande chmod modifie les permissions associées à cet utilisateur et au groupe, ainsi qu’à d’autres.

      Ensuite, vous allez créer un fichier info.php à l’intérieur du répertoire root de chaque site Web. Cela affichera les informations de version PHP de chaque site Web. Commencez avec site1

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

      Ajoutez la ligne suivante :

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

      <?php phpinfo(); ?>
      

      Enregistrez et fermez le fichier. Copiez maintenant le fichier info.php que vous avez créé sur site2

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

      Votre serveur web dispose maintenant des répertoires racine des documents dont chaque site a besoin pour fournir des données aux visiteurs. Ensuite, vous allez configurer votre serveur web Apache pour qu’il fonctionne avec deux versions PHP différentes.

      Étape 3 — Configuration d’Apache pour les deux sites Web

      Dans cette section, vous allez créer deux fichiers de configuration d’hôte virtuel. Cela permettra à vos deux sites web de fonctionner simultanément avec deux versions PHP différentes.

      Pour qu’Apache puisse servir ce contenu, il est nécessaire de créer un fichier d’hôte virtuel avec les directives correctes. Vous allez créer deux nouveaux fichiers de configuration d’hôte virtuel dans le répertoire /etc/httpd/conf.d/.

      Commencez par créer un nouveau fichier de configuration d’hôte virtuel pour le site Web site1.your_domain. Ici, vous allez indiquer à Apache de rendre le contenu en utilisant PHP 7.0 :

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

      Ajoutez le contenu suivant. Assurez-vous le chemin du répertoire du site Web, le nom du serveur, le port et la version PHP correspondent à votre configuration :

      /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>
      

      Pour DocumentRoot, vous spécifiez le chemin du répertoire racine de votre site web. Pour ServerAdmin, vous ajoutez un courriel auquel l’administrateur du site your_domain peut accéder. Pour ServerName, vous ajoutez l’url de votre premier sous-domaine. Pour SetHandler, vous spécifiez le port 9002. Les autres directives configurent également votre service pour déployer PHP 7.0.

      Enregistrez et fermez le fichier.

      Ensuite, créez un nouveau fichier de configuration d’hôte virtuel pour le site Web site2.your_domain. Vous allez spécifier ce sous domaine pour déployer PHP 7.2 :

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

      Ajoutez le contenu suivant. Là encore, assurez-vous que le chemin d’accès au répertoire du site web, le nom du serveur, le port et la version PHP correspondent à vos informations uniques :

      /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>
      

      Enregistrez et fermez le fichier lorsque vous avez terminé. Vérifiez ensuite le fichier de configuration Apache pour détecter toute erreur de syntaxe :

      • sudo apachectl configtest

      Vous verrez une sortie d’impression Syntax OK :

      Output

      Enfin, redémarrez le service Apache pour implémenter vos changements :

      • sudo systemctl restart httpd

      Maintenant que vous avez configuré Apache pour servir chaque site, vous allez tester les sites pour vous assurer que les versions PHP adéquates tournent.

      Étape 4 — Test des deux sites Web

      À ce stade, vous avez configuré deux sites web pour exécuter deux versions différentes de PHP. Testez maintenant les résultats.

      Ouvrez votre navigateur web et consultez les deux sites http://site1.your_domain et http://site2.your_domain Vous verrez deux pages qui ressemblent à ceci :

      PHP 7.0 info pagePHP 7.2 info page

      Notez les titres. La première page indique que site1.your_domain a déployé PHP version 7.0. La deuxième indique que site2.your_domain a déployé PHP version 7.2.

      Maintenant que vous avez testé vos sites, supprimez les fichiers info.php. Étant donné qu’ils contiennent des informations sensibles sur votre serveur et sont accessibles a des utilisateurs non autorisés, ils constituent une faille de sécurité. Supprimez les fichiers :

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

      Vous disposez désormais d’un seul serveur CentOS 7 qui gère deux sites web avec deux versions différentes de PHP. Cela dit, PHP-FPM n’est pas limité à cette seule application.

      Conclusion

      Vous avez maintenant combiné des hôtes virtuels et PHP-FPM pour servir plusieurs sites web et plusieurs versions de PHP sur un seul serveur. La seule limite pratique sur le nombre de sites PHP et les versions PHP que votre service Apache peut gérer est la puissance de traitement de votre instance.

      À partir de là, vous pourriez envisager d’explorer les fonctionnalités plus avancées de PHP-FPM, comme son processus de spawning adaptatif ou la façon dont il peut enregistrer sdtout et stderr.  Par ailleurs, vous pourriez désormais sécuriser vos sites web. Pour ce faire, vous pouvez suivre notre tutoriel sur comment sécuriser vos sites avec des certificats TLS/SSL gratuits de Let’s Encrypt.



      Source link

      Comment exécuter plusieurs Versions PHP sur un serveur en utilisant Apache et PHP-FPM sur Debian 10


      L’auteur a choisi le COVID-19 Relief Fund pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      Le serveur web Apache utilise des hôtes virtuels pour gérer plusieurs domaines sur une seule instance. De même, PHP-FPM utilise un démon pour gérer plusieurs versions PHP sur une seule instance. Vous pouvez utiliser ensemble Apache et PHP-FPM pour héberger plusieurs applications Web PHP, chacune utilisant une version différente de PHP, toutes sur le même serveur, et toutes en même temps. C’est utile car différentes applications peuvent nécessiter différentes versions de PHP, mais certaines piles de serveurs, telles qu’une pile LAMP régulièrement configurée, ne peuvent gérer qu’une seule version. Combiner Apache avec PHP-FPM est également une solution plus économique que d’héberger chaque application sur sa propre instance.

      PHP-FPM offre également des options de configuration pour la journalisation stderr et stdout, les redémarrages d’urgence et le lancement de processus adaptatifs, ce qui est utile pour les sites très chargés. En fait, l’utilisation d’Apache avec PHP-FPM est l’une des meilleures piles pour héberger des applications PHP, surtout en matière de performances.

      Dans ce tutoriel, vous allez configurer deux sites PHP sur une seule instance. Chaque site utilisera son propre domaine, et chaque domaine déploiera sa propre version de PHP. Le premier, site1.your_domain, déploiera PHP 7.0. La deuxième, site2.your_domain, déploiera PHP 7.2.

      Conditions préalables

      Étape 1 – Installation des Versions PHP 7.0 et 7.2 avec PHP-FPM

      Une fois les conditions préalables remplies, vous allez maintenant installer les versions 7.0 et 7.2, ainsi que PHP-FPM et plusieurs extensions supplémentaires. Mais pour ce faire, vous devrez d’abord ajouter le référentiel sury php à votre système.

      Installez d’abord les différents paquets nécessaires, notamment curl, wget, and gnupg2 :

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

      Les paquets ci-dessus vous permettront d’accéder au référentiel sury php, et ce de manière sécurisée. sury php est un référentiel tiers ou PPA (personal package archive ou dépôts personnels de paquets logiciels, en français). Il offre PHP 7.4, 7.3, 7.2, 7.1, et 7.0 pour le système d’exploitation Debian. Il offre également des versions plus récentes de PHP que les référentiels officiels de Debian 10 et vous permettra d’installer plusieurs versions de PHP sur le même système.

      Ensuite, importez la clé du paquet :

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

      Ajoutez maintenant le référentiel sury php à votre système :

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

      Mettez le référentiel à jour :

      Ensuite, installez php7.0, php7.0-fpm, php7.0-mysql, libapache2-mod-php7.0 et libapache2-mod-fcgid avec les commandes suivantes

      • sudo apt-get install php7.0 php7.0-fpm php7.0-mysql libapache2-mod-php7.0 libapache2-mod-fcgid -y
      • php7.0 est un meta package qui peut être utilisé pour exécuter des applications PHP.
      • php7.0-fpm fournit l’interprète Fast Process Manager qui fonctionne comme démon et reçoit des requêtes Fast/CGI.
      • php7.0-mysql connecte PHP à la base de données MySQL.
      • libapahce2-mod-php7.0 fournit le module PHP pour le serveur Apache.
      • libapache2-mod-fcgid contient un mod_fcgid qui lance un certain nombre d’instances de programme CGI pour traiter les requêtes simultanées.

      Repérez maintenant le processus pour la version PHP 7.2. Installez php7.2, php7.2-fpm, php7.2-mysql, et libapache2-mod-php7.2 :

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

      Après avoir installé les deux versions PHP, lancez le service php7.0-fpm

      • sudo systemctl start php7.0-fpm

      Ensuite, vérifiez l’état du service php7.0-fpm

      • sudo systemctl status php7.0-fpm

      Vous verrez la sortie suivante :

      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.

      En répétant ce processus, lancez maintenant le service php7.2-fpm :

      • sudo systemctl start php7.2-fpm

      Vérifiez ensuite l’état du service php7.2-fpm :

      • sudo systemctl status php7.2-fpm

      Vous verrez la sortie suivante :

      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.

      Et enfin, vous devez activer plusieurs modules pour que votre service Apache2 puisse fonctionner avec plusieurs versions PHP :

      • sudo a2enmod actions fcgid alias proxy_fcgi
      • actions est utilisé pour exécuter des scripts CGI sur la base de type de média ou de méthode de requête.

      • fcgid est une alternative haute performance à mod_cgi qui démarre un nombre suffisant d’instances du programme CGI pour traiter des requêtes simultanées.

      • alias permet le mappage des différentes parties du système de fichiers hôte dans l’arborescence du document, et la redirection des URL.

      • proxy_fcgi permet à Apache de transmettre des requêtes à PHP-FPM.

      Redémarrez maintenant le service Apache pour appliquer vos modifications :

      • sudo systemctl restart apache2

      À ce stade, vous avez installé deux versions PHP sur votre serveur. Ensuite, vous allez créer une structure de répertoire pour chaque site web que vous voulez déployer.

      Étape 2 — Création de structures répertoire pour les deux sites Web

      Dans cette section, vous créerez un répertoire root de document et une page index pour chacun de vos deux sites Web.

      Tout d’abord, créez des répertoires root de documents à la fois pour site1.your_domain et site2.your_domain

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

      Par défaut, le serveur Apache fonctionne comme un utilisateur www-data et un groupe www-data. Pour vous assurer que vous avez la propriété et les permissions correctes des répertoires root de votre site web, exécutez les commandes suivantes :

      • 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

      Ensuite, vous allez créer un fichier info.php à l’intérieur du répertoire root de chaque site Web. Cela affichera les informations de version PHP de chaque site Web. Commencez avec site1

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

      Ajoutez la ligne suivante :

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

      <?php phpinfo(); ?>
      

      Enregistrez et fermez le fichier. Copiez maintenant le fichier info.php que vous avez créé sur site2

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

      Votre serveur web devrait maintenant disposer des répertoires racine de documents dont chaque site a besoin pour fournir des données aux visiteurs. Ensuite, vous allez configurer votre serveur web Apache pour qu’il fonctionne avec deux versions PHP différentes.

      Étape 3 — Configuration d’Apache pour les deux sites Web

      Dans cette section, vous allez créer deux fichiers de configuration d’hôte virtuel. Cela permettra à vos deux sites web de fonctionner simultanément avec deux versions PHP différentes.

      Pour qu’Apache puisse servir ce contenu, il est nécessaire de créer un fichier d’hôte virtuel avec les directives correctes. Au lieu de modifier le fichier de configuration par défaut situé à /etc/apache2/sites-available/000-default.conf​​​, vous allez en créer deux nouveaux dans le répertoire /etc/apache2/sites-available/​​​.

      Commencez par créer un nouveau fichier de configuration d’hôte virtuel pour le site Web site1.your_domain. Ici, vous allez indiquer à Apache de rendre le contenu en utilisant php7.0 :

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

      Ajoutez le contenu suivant. Assurez-vous le chemin du répertoire du site Web, le nom du serveur et la version PHP correspondent à votre configuration :

      /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>
      

      Dans ce fichier, vous avez mis à jour le DocumentRoot sur votre nouveau répertoire et ServerAdmin à un email auquel l’administrateur du site your_domain peut accéder. Vous avez également mis à jour ServerName, qui établit le domaine de base pour cette configuration d’hôte virtuel, et vous avez ajouté une directive SetHandler pour exécuter PHP en tant que serveur de processus fastCGI

      Enregistrez et fermez le fichier.

      Ensuite, créez un nouveau fichier de configuration d’hôte virtuel pour le site Web site2.your_domain. Vous allez spécifier ce sous domaine pour déployer php7.2

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

      Ajoutez le contenu suivant. Là encore, assurez-vous que le chemin d’accès au répertoire du site web, le nom du serveur et la version PHP correspondent à vos informations uniques :

      /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>
      

      Enregistrez et fermez le fichier lorsque vous avez terminé. Vérifiez ensuite le fichier de configuration Apache pour détecter toute erreur de syntaxe :

      • sudo apachectl configtest

      Vous verrez la sortie suivante :

      Output

      Syntax OK

      Ensuite, activez les deux fichiers de configuration d’hôte virtuel :

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

      Désactivez maintenant le site par défaut, puisque vous n’en aurez pas besoin :

      • sudo a2dissite 000-default.conf

      Enfin, redémarrez le service Apache pour implémenter vos changements :

      • sudo systemctl restart apache2

      Maintenant que vous avez configuré Apache pour servir chaque site, vous allez les tester pour vous assurer que les versions PHP adéquates tournent.

      Étape 4 — Test des deux sites Web

      À ce stade, vous avez configuré deux sites web pour exécuter deux versions différentes de PHP. Testez maintenant les résultats.

      Ouvrez votre navigateur web et consultez les deux sites http://site1.your_domain et http://site2.your_domain Vous verrez deux pages qui ressemblent à ceci :

      PHP 7.0 info pagePHP 7.2 info page

      Notez les titres. La première page indique que site1.your_domain a déployé PHP version 7.0. La deuxième indique que site2.your_domain a déployé PHP version 7.2.

      Maintenant que vous avez testé vos sites, supprimez les fichiers info.php. Étant donné qu’ils contiennent des informations sensibles sur votre serveur et sont accessibles aux utilisateurs non autorisés, ils constituent une menace de sécurité. Pour supprimer les deux fichiers, exécutez les commandes suivantes :

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

      Vous disposez maintenant d’un seul serveur Debian 10 qui gère deux sites web avec deux versions PHP différentes. Cela dit, PHP-FPM n’est pas limité à cette seule application.

      Conclusion

      Vous avez maintenant combiné des hôtes virtuels et PHP-FPM pour servir plusieurs sites web et plusieurs versions de PHP sur un seul serveur. La seule limite pratique sur le nombre de sites PHP et les versions PHP que votre service Apache peut gérer est la puissance de traitement de votre instance.

      À partir de là, vous pouvez envisager d’explorer les fonctionnalités les plus avancées de PHP-FPM, comme son processus de spawning adaptatif ou la façon dont il peut enregistrer sdtout et stderr. Sinon, vous pouvez maintenant sécuriser vos sites web. Pour ce faire, vous pouvez suivre notre tutoriel sur comment sécuriser vos sites avec des certificats TLS/SSL gratuits de Let’s Encrypt.



      Source link