One place for hosting & domains

      Executar

      Como usar o subprocess para executar programas externos em Python 3


      O autor selecionou a COVID-19 Relief Fund​​​​​ para receber uma doação como parte do programa Write for DOnations.

      Introdução

      O Python 3 inclui o módulo subprocess para executar programas externos e ler suas saídas em seu código Python.

      Você pode achar o subprocess útil se quiser usar outro programa em seu computador dentro do seu código Python. Por exemplo, você pode querer invocar o git dentro do seu código Python para recuperar arquivos em seu projeto que são rastreados no controle de versão git. Como qualquer programa que você possa acessar em seu computador pode ser controlado pelo subprocess, os exemplos mostrados aqui serão aplicáveis a qualquer programa externo que você queira invocar a partir do seu código Python.

      O subprocess inclui várias classes e funções, mas neste tutorial, vamos cobrir uma das funções mais úteis do subprocess: subprocess.run. Vamos revisar seus diferentes usos e principais argumentos de palavra-chave.

      Pré-requisitos

      Para tirar o máximo proveito deste tutorial, recomenda-se ter alguma familiaridade com programação em Python 3. Você pode revisar esses tutoriais para as informações básicas necessárias:

      Executando um programa externo

      Você pode usar a função subprocess.run para executar um programa externo a partir do seu código Python. Primeiro, porém, você precisa importar os módulos subprocess e sys para seu programa:

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

      Se você executar isso, receberá uma saída como a seguinte:

      Output

      ocean

      Vamos revisar este exemplo:

      • sys.executable é o caminho absoluto para o executável Python com o qual seu programa foi originalmente invocado. Por exemplo, sys.executable pode ser um caminho como /usr/local/bin/python.
      • subprocess.run recebe uma lista de strings que consistem nos componentes do comando que estamos tentando executar. Como a primeira string que passamos é sys.executable, estamos instruindo subprocess.run a executar um novo programa Python.
      • O componente -c é uma opção de linha de comando python que lhe permite passar uma string com um programa Python inteiro para executar. Em nosso caso, passamos um programa que imprime a string ocean.

      Você pode pensar em cada entrada na lista que passamos para subprocess.run como sendo separadas por um espaço. Por exemplo, [sys.executable, "-c", "print('ocean')"] traduz aproximadamente para /usr/local/bin/python -c "print('ocean')". Observe que o subprocess automaticamente coloca aspas nos componentes do comando antes de tentar executá-los no sistema operacional subjacente para que, por exemplo, você possa passar um nome de arquivo que tenha espaços nele.

      Atenção: nunca passe entrada não confiável para subprocess.run. Como o subprocess.run tem a capacidade de executar comandos arbitrários em seu computador, indivíduos maliciosos podem usá-lo para manipular seu computador de maneiras inesperadas.

      Capturando a saída de um programa externo

      Agora que podemos invocar um programa externo usando subprocess.run, vamos ver como podemos capturar a saída desse programa. Por exemplo, este processo poderia ser útil se quiséssemos usar git ls-files para exibir todos os seus arquivos atualmente armazenados sob o controle de versão.

      Nota: os exemplos mostrados nesta seção exigem Python 3.7 ou superior. Em particular, os argumentos de palavra-chave capture_output e text foram adicionados ao Python 3.7 quando ele foi lançado em junho de 2018.

      Vamos adicionar ao nosso exemplo anterior:

      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)
      

      Se executarmos esse código, receberemos um resultado como o seguinte:

      Output

      stdout: ocean stderr:

      Este exemplo é em grande parte o mesmo que o introduzido na primeira seção: ainda estamos executando um subprocesso para imprimir ocean. É importante ressaltar, no entanto, que passamos os argumentos de palavra-chave capture_output=True e text=True para subprocess.run.

      subprocess.run retorna um objeto subprocess.CompletedProcess que está vinculado a result. O objeto subprocess.CompletedProcess inclui detalhes sobre o código de saída do programa externo e sua saída. capture_output=True garante que result.stdout e result.stderr estejam preenchidos com a saída correspondente do programa externo. Por padrão, result.stdout e result.stderr são vinculados como bytes, mas o argumento de palavra-chave text=True instrui o Python a, em vez disso, decodificar os bytes em strings.

      Na seção output stdout é ocean (mais uma nova linha final que print adiciona implicitamente), e não temos nenhum stderr.

      Vamos tentar um exemplo que produz um valor não vazio para 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)
      

      Se executarmos esse código, receberemos uma saída como a seguinte:

      Output

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

      Este código executa um subprocesso Python que imediatamente gera um erro de ValueError. Quando inspecionamos o result final, não vemos nada em stdout e um Traceback de nosso ValueError em stderr. Isso ocorre porque, por padrão, o Python escreve o Traceback da exceção não tratada em stderr.

      Gerando uma exceção em um código de saída ruim

      Às vezes, é útil gerar uma exceção se um programa que executamos termine com um código de saída ruim. Os programas que terminam com um código zero são considerados bem sucedidos, mas programas que terminam com um código não zero são considerados como tendo encontrado um erro. Como um exemplo, esse padrão poderia ser útil se quiséssemos gerar uma exceção no caso em que executamos git ls-files em um diretório que não fosse realmente um repositório git.

      Podemos usar o argumento de palavra-chave check=True para subprocess.run para ter uma exceção gerada se o programa externo retornar um código de saída não zero:

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

      Se executarmos esse código, receberemos uma saída como a seguinte:

      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.

      Esta saída mostra que executamos um subprocesso que gerou um erro, que é impresso em stderr em nosso terminal. Em seguida, subprocess.run criou devidamente um subprocess.CalledProcessError por nós em nosso programa Python principal.

      Alternativamente, o módulo subprocess também inclui o método subprocess.CompletedProcess.check_returncode, que podemos invocar para um efeito semelhante:

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

      Se executarmos este código, receberemos:

      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.

      Como não passamos check=True para subprocess.run, vinculamos com sucesso uma instância de subprocess.CompletedProcess a result, mesmo que nosso programa seja encerrado com um código diferente de zero. Chamar result.check_returncode(), no entanto, gera um subprocess.CalledProcessError porque ele detecta que o processo finalizado foi encerrado com um código ruim.

      Usando o timeout para sair de programas mais cedo

      subprocess.run inclui o argumento timeout para permitir que você pare um programa externo se estiver levando muito tempo para executar:

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

      Se executarmos esse código, receberemos um resultado como o seguinte:

      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

      O subprocesso que tentamos executar usou a função time.sleep para colocá-lo em repouso por 2 segundos. No entanto, passamos o argumento de palavra-chave timeout=1 para subprocess.run para expirar nosso subprocesso após 1 segundo. Isso explica por que nossa chamada para subprocess.run finalmente gerou uma exceção subprocess.TimeoutExpired.

      Observe que o argumento de palavra-chave timeout para subprocess.run é aproximado. Python fará um melhor esforço para matar o subprocesso após o número de segundos de timeout, mas ele não será necessariamente exato.

      Passando a entrada para programas

      Às vezes, os programas esperam que a entrada seja passada para eles via stdin.

      O argumento de palavra-chave input para subprocess.run permite que você passe dados para o stdin do subprocesso. Por exemplo:

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

      Receberemos uma saída como a seguinte depois de executar este código:

      Output

      underwater

      Neste caso, passamos os bytes underwater para input. Nosso subprocesso alvo usou sys.stdin para ler o que foi passado em stdin (underwater) e o imprimiu em nossa saída.

      O argumento de palavra-chave input pode ser útil se você quiser encadear várias chamadas subprocess.run juntas passando a saída de um programa como a entrada para outro.

      Conclusão

      O módulo subprocess é uma parte poderosa da biblioteca padrão Python que permite que você execute programas externos e inspecione suas saídas com facilidade. Neste tutorial, você aprendeu a usar subprocess.run para controlar programas externos, passar a entrada para eles, analisar sua saída e verificar seus códigos de retorno.

      O módulo subprocess expõe classes e utilitários adicionais que não abordamos neste tutorial. Agora que você tem um conhecimento básico, você pode usar a documentação do módulo subprocess para aprender mais sobre outras classes e utilitários disponíveis.



      Source link

      Como executar várias versões do PHP em um servidor usando o Apache e o PHP-FPM no Debian 10


      O autor selecionou a COVID-19 Relief Fund​​​​​ para receber uma doação como parte do programa Write for DOnations.

      Introdução

      O servidor Web do Apache usa hosts virtuais para gerenciar vários domínios em uma única instância. De igual modo, o PHP-FPM utiliza um daemon para gerenciar várias versões de PHP em uma única instância. Você pode usar o Apache e o PHP-FPM juntos para hospedar vários aplicativos Web em PHP, cada qual usando uma versão diferente de PHP, porém todas as versões em um mesmo servidor e ao mesmo tempo. Isso é útil, pois diferentes aplicativos exigem diferentes versões de PHP. Porém, algumas pilhas de servidor – como uma pilha LAMP configurada regularmente – podem gerenciar somente uma versão de PHP. A combinação do Apache com o PHP-FPM também é uma solução mais econômica do que hospedar cada aplicativo em sua própria instância.

      O PHP-FPM também oferece opções de configuração para o acesso ao stderr e ao stdout, reinicializações de emergência e geração de processos adaptáveis, o que é útil para sites muito carregados. Na verdade, o uso do Apache com o PHP-FPM é uma das melhores pilhas para a hospedagem de aplicativos PHP, especialmente em relação ao desempenho.

      Neste tutorial, você configurará dois sites PHP em uma única instância. Cada site usará seu próprio domínio e cada domínio implantará sua própria versão de PHP. O primeiro,site1.your_domain, implantará o PHP 7.0. O segundo, site2.your_domain, implantará o PHP 7.2.

      Pré-requisitos

      Com os pré-requisitos concluídos, você instalará as versões 7.0 e 7.2 do PHP, além do PHP-FPM e várias extensões adicionais. Mas para isso, primeiro será necessário adicionar o repositório sury php ao seu sistema.

      Primeiro, instale os diversos pacotes necessários, entre eles o curl, o wget e o gnupg2:

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

      Os pacotes acima permitirão, de maneira segura, o seu acesso ao repositório sury php. O sury php é um repositório de terceiros ou um PPA (arquivo de pacote pessoal). Ele oferece o PHP nas versões 7.4, 7.3, 7.2, 7.1 e 7.0 para o sistema operacional Debian. Este repositório também oferece versões mais recentes do PHP do que aquelas encontradas nos repositórios oficiais do Debian 10, e permitirá que você instale várias versões do PHP no mesmo sistema.

      Em seguida, importe a chave do pacote:

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

      Agora, adicione o repositório sury php ao seu sistema:

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

      Atualize o repositório:

      Em seguida, instale o php7.0, o php7.0-fpm, o php7.0-mysql, o libapache2-mod-php7.0 e o libapache2-mod-fcgid com os comandos a seguir:

      • sudo apt-get install php7.0 php7.0-fpm php7.0-mysql libapache2-mod-php7.0 libapache2-mod-fcgid -y
      • O php7.0 é um metapacote que pode ser utilizado para executar aplicativos PHP.
      • O php7.0-fpm fornece o interpretador do gerenciador de processos rápidos que funciona como um daemon e recebe solicitações do Fast/CGI.
      • O php7.0-mysql conecta o PHP ao banco de dados MySQL.
      • O libapache2-mod-php7.0 fornece o módulo PHP para o servidor Web do Apache.
      • O libapache2-mod-fcgid contém um mod_fcgid que inicia uma série de instâncias do programa CGI para tratar solicitações simultâneas.

      Agora, repita o processo para a versão PHP 7.2. Instale o php7.2, o php7.2-fpm, o php7.2-mysql e o libapache2-mod-php7.2.

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

      Após instalar ambas as versões do PHP, inicie o serviço php7.0-fpm:

      • sudo systemctl start php7.0-fpm

      Em seguida, verifique o status do serviço php7.0-fpm:

      • sudo systemctl status php7.0-fpm

      Você verá o seguinte resultado:

      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.

      Repetindo esse processo, agora inicie o serviço php7.2-fpm:

      • sudo systemctl start php7.2-fpm

      E, em seguida, verifique o status do serviço php7.2-fpm:

      • sudo systemctl status php7.2-fpm

      Você verá o seguinte resultado:

      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.

      Por fim, você deve habilitar vários módulos para que o seu serviço Apache2 possa funcionar com várias versões do PHP:

      • sudo a2enmod actions fcgid alias proxy_fcgi
      • As actions são usadas para executar scripts de CGI baseados no tipo de mídia, ou método de solicitação.

      • O fcgid é uma alternativa de alto desempenho ao mod_cgi, que inicia um número suficiente de instâncias do programa CGI para processar solicitações simultâneas.

      • O alias dá suporte ao mapeamento de diferentes partes do sistema de arquivos do host na árvore de documentos e ao redirecionamento da URL.

      • O proxy_fcgi permite que o Apache encaminhe solicitações para o PHP-FPM.

      Agora, reinicie o serviço do Apache para aplicar suas alterações:

      • sudo systemctl restart apache2

      Neste ponto, você instalou duas versões do PHP em seu servidor. Em seguida, você criará uma estrutura de diretório para cada site que deseja implantar.

      Passo 2 — Criando estruturas de diretório para ambos os sites

      Nesta seção, você criará um diretório para o diretório base e uma página de índice para cada um dos seus dois sites.

      Primeiro, crie os diretórios de diretório base para os dois sites, o site1.your_domain e o site2.your_domain:

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

      Por padrão, o servidor Web do Apache funciona como um usuário www-data e um grupo www-data. Para garantir que você tenha a propriedade e as permissões corretas de seus diretórios base de seu site, execute os comandos a seguir:

      • 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

      Em seguida, você criará um arquivo info.php dentro do diretório base de cada site. Isso exibirá as informações da versão do PHP de cada site. Comece com o site1:

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

      Adicione a linha a seguir:

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

      <?php phpinfo(); ?>
      

      Salve e feche o arquivo. Agora, copie o arquivo info.php que você criou para o site2:

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

      Agora, o seu servidor Web deverá ter os diretórios de documento base que cada site exige para fornecer dados aos visitantes. Em seguida, você configurará seu servidor Web do Apache para funcionar com duas versões diferentes do PHP.

      Passo 3 — Configurando o Apache para ambos os sites

      Nesta seção, você criará dois arquivos de configuração do host virtual. Isso permitirá que seus dois sites funcionem simultaneamente com duas versões diferentes do PHP.

      Para que o Apache distribua esse conteúdo, é necessário criar um arquivo de host virtual com as diretivas corretas. Em vez de modificar o arquivo de configuração padrão, localizado em /etc/apache2/sites-available/000-default.conf, você criará dois novos arquivos dentro do diretório /etc/apache2/sites-available/.

      Primeiro,crie um novo arquivo de configuração de host virtual para o site site1.your_domain. Aqui, você direcionará o Apache a renderizar o conteúdo usando o php7.0:

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

      Adicione o conteúdo a seguir: Verifique se o caminho do diretório do site, o nome do servidor e a versão de PHP correspondem à sua configuração:

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

      Neste arquivo, você atualizou o DocumentRoot para o seu novo diretório e o ServerAdmin para um e-mail que o administrador do site your_domain pode acessar. Você também atualizou o ServerName, o qual estabelece o domínio base dessa configuração do host virtual, bem como adicionou uma diretiva SetHandler para executar o PHP como um servidor de processos fastCGI.

      Salve e feche o arquivo.

      Em seguida, crie um novo arquivo de configuração de host virtual para o site site2.your_domain. Você especificará este subdomínio para implantar o php7.2:

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

      Adicione o conteúdo a seguir: Novamente, verifique se o caminho do diretório do site, o nome do servidor e a versão PHP correspondem às suas informações únicas:

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

      Salve e feche o arquivo quando você terminar. Em seguida, verifique se há erros de sintaxe no arquivo de configuração do Apache:

      • sudo apachectl configtest

      Você verá o seguinte resultado:

      Output

      Syntax OK

      Agora, habilite ambos os arquivos de configuração de host virtual:

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

      Você não precisará do site padrão. Desabilite-o:

      • sudo a2dissite 000-default.conf

      Finalmente, reinicie o serviço do Apache para implementar suas alterações:

      • sudo systemctl restart apache2

      Após configurar o Apache para atender a cada site, você os testará para garantir que as versões apropriadas do PHP estejam funcionando corretamente.

      Passo 4 — Testando os sites

      Até aqui, você já configurou dois sites para executar duas versões diferentes do PHP. Agora, teste os resultados.

      Abra seu navegador Web e visite os dois sites http://site1.your_domain e http://site2.your_domain. Você verá duas páginas parecidas com estas:

      Página de informações do PHP 7.0Página de informações do PHP 7.2

      Observe os títulos. A primeira página indica que o site1.your_domain implantou o PHP 7.0. A segunda indica que o site2.your_domain implantou o PHP 7.2.

      Agora que você testou seus sites, remova os arquivos info.php. Como eles contêm informações confidenciais sobre seu servidor e estão acessíveis a usuários não autorizados, eles representam uma ameaça à segurança. Para remover os dois arquivos, execute os comandos a seguir:

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

      Agora, você tem um único servidor Debian 10 cuidando de dois sites, com duas versões diferentes do PHP. No entanto, o PHP-FPM não está limitado a este aplicativo.

      Conclusão

      Você combinou os hosts virtuais e o PHP-FPM para atender vários sites e várias versões do PHP em um único servidor. O único limite prático sobre o número de sites PHP e de versões do PHP que o seu serviço do Apache pode gerenciar é a capacidade de processamento de sua instância.

      A partir daqui, considere explorar recursos mais avançados do PHP-FPM, como sua geração de processos adaptáveis ou a maneira como ele pode acessar o sdtout e o stderr. Como uma alternativa, você pode agora proteger seus sites. Para fazer isso, você pode seguir nosso tutorial sobre como proteger seus sites com certificados TLS/SSL gratuitos do Let’s Encrypt.



      Source link

      Como executar várias versões do PHP em um servidor usando o Apache e o PHP-FPM no Ubuntu 18.04


      O autor selecionou a COVID-19 Relief Fund​​​​​ para receber uma doação como parte do programa Write for DOnations.

      Introdução

      O servidor Web do Apache usa hosts virtuais para gerenciar vários domínios em uma única instância. De igual modo, o PHP-FPM utiliza um daemon para gerenciar várias versões de PHP em uma única instância. Você pode usar o Apache e o PHP-FPM juntos para hospedar vários aplicativos Web em PHP, cada qual usando uma versão diferente de PHP, porém todas as versões em um mesmo servidor e ao mesmo tempo. Isso é útil, pois diferentes aplicativos exigem diferentes versões de PHP. Porém, algumas pilhas de servidor – como uma pilha LAMP configurada regularmente – podem gerenciar somente uma versão de PHP. A combinação do Apache com o PHP-FPM também é uma solução mais econômica do que hospedar cada aplicativo em sua própria instância.

      O PHP-FPM também oferece opções de configuração para o acesso ao stderr e ao stdout, reinicializações de emergência e geração de processos adaptáveis, o que é útil para sites muito carregados. Na verdade, o uso do Apache com o PHP-FPM é uma das melhores pilhas para a hospedagem de aplicativos PHP, especialmente em relação ao desempenho.

      Neste tutorial, você configurará dois sites PHP em uma única instância. Cada site usará seu próprio domínio e cada domínio implantará sua própria versão de PHP. O primeiro,site1.your_domain, implantará o PHP 7.0. O segundo, site2.your_domain, implantará o PHP 7.2.

      Pré-requisitos

      Com os pré-requisitos concluídos, você instalará as versões 7.0 e 7.2 do PHP, além do PHP-FPM e várias extensões adicionais. Mas para realizar isso, primeiro você precisará adicionar o repositório Ondrej PHP ao seu sistema.

      Execute o comando apt-get para instalar o software-properties-common:

      • sudo apt-get install software-properties-common -y

      O pacote software-properties-common fornece o utilitário de linha de comando apt-add-repository, o qual você utilizará para adicionar o repositório PPA(arquivo de pacote pessoal) ondrej/php.

      Agora, adicione o repositório ondrej/php ao seu sistema. O PPA ondrej/php terá versões mais recentes do PHP do que as encontradas nos repositórios oficiais do Ubuntu. Ele também permitirá que instale várias versões do PHP no mesmo sistema:

      • sudo add-apt-repository ppa:ondrej/php

      Atualize o repositório:

      Em seguida, instale o php7.0, o php7.0-fpm, o php7.0-mysql, o libapache2-mod-php7.0 e o libapache2-mod-fcgid com os comandos a seguir:

      • sudo apt-get install php7.0 php7.0-fpm php7.0-mysql libapache2-mod-php7.0 libapache2-mod-fcgid -y
      • O php7.0 é um metapacote utilizado para executar aplicativos PHP.
      • O php7.0-fpm fornece o interpretador do gerenciador de processos rápidos que funciona como um daemon e recebe solicitações do Fast/CGI.
      • O php7.0-mysql conecta o PHP ao banco de dados MySQL.
      • O libapache2-mod-php7.0 fornece o módulo PHP para o servidor Web do Apache.
      • O libapache2-mod-fcgid contém um mod_fcgid que inicia uma série de instâncias do programa CGI para tratar solicitações simultâneas.

      Agora, repita o processo para a versão PHP 7.2. Instale o php7.2, o php7.2-fpm, o php7.2-mysql e o libapache2-mod-php7.2:

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

      Após instalar ambas as versões do PHP, inicie o serviço php7.0-fpm:

      • sudo systemctl start php7.0-fpm

      Em seguida, verifique o status do serviço php7.0-fpm:

      • sudo systemctl status php7.0-fpm

      Você verá o seguinte resultado:

      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 Sun 2020-03-29 12:53:23 UTC; 15s ago Docs: man:php-fpm7.0(8) Process: 20961 ExecStopPost=/usr/lib/php/php-fpm-socket-helper remove /run/php/php-fpm.sock /etc/php/7.0/fpm/pool.d/www.conf 70 (code=exited, Process: 20979 ExecStartPost=/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/7.0/fpm/pool.d/www.conf 70 (code=exite Main PID: 20963 (php-fpm7.0) Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec" Tasks: 3 (limit: 1150) CGroup: /system.slice/php7.0-fpm.service ├─20963 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf) ├─20977 php-fpm: pool www └─20978 php-fpm: pool www

      Repetindo esse processo, agora inicie o serviço php7.2-fpm:

      • sudo systemctl start php7.2-fpm

      E verifique o status do serviço php7.2-fpm:

      • sudo systemctl status php7.2-fpm

      Você verá o seguinte resultado:

      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 Sun 2020-03-29 12:53:22 UTC; 45s ago Docs: man:php-fpm7.2(8) Main PID: 20897 (php-fpm7.2) Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec" Tasks: 3 (limit: 1150) CGroup: /system.slice/php7.2-fpm.service ├─20897 php-fpm: master process (/etc/php/7.2/fpm/php-fpm.conf) ├─20909 php-fpm: pool www └─20910 php-fpm: pool www

      Por fim, você deve habilitar vários módulos para que o seu serviço Apache2 possa funcionar com várias versões do PHP:

      • sudo a2enmod actions fcgid alias proxy_fcgi
      • As actions são usadas para executar scripts de CGI baseados no tipo de mídia, ou método de solicitação.

      • O fcgid é uma alternativa de alto desempenho ao mod_cgi, que inicia um número suficiente de instâncias do programa CGI para processar solicitações simultâneas.

      • O alias dá suporte ao mapeamento de diferentes partes do sistema de arquivos do host na árvore de documentos e ao redirecionamento da URL.

      • O proxy_fcgi permite que o Apache encaminhe solicitações para o PHP-FPM.

      Agora, reinicie o serviço do Apache para aplicar suas alterações:

      • sudo systemctl restart apache2

      Neste ponto, você instalou duas versões do PHP em seu servidor. Em seguida, você criará uma estrutura de diretório para cada site que deseja implantar.

      Passo 2 — Criando estruturas de diretório para ambos os sites

      Nesta seção, você criará um diretório para o diretório base e uma página de índice para cada um dos seus dois sites.

      Primeiro, crie os diretórios de diretório base para os dois sites, o site1.your_domain e o site2.your_domain:

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

      Por padrão, o servidor Web do Apache funciona como um usuário www-data e um grupo www-data. Para garantir que você tenha a propriedade e as permissões corretas de seus diretórios base de seu site, execute os comandos a seguir:

      • 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

      Em seguida, você criará um arquivo info.php dentro do diretório base de cada site. Isso exibirá as informações da versão do PHP de cada site. Comece com o site1:

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

      Adicione a linha a seguir:

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

      <?php phpinfo(); ?>
      

      Salve e feche o arquivo. Agora, copie o arquivo info.php que você criou para o site2:

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

      Agora, o seu servidor Web deverá ter os diretórios de documento base que cada site exige para fornecer dados aos visitantes. Em seguida, você configurará seu servidor Web do Apache para funcionar com duas versões diferentes do PHP.

      Passo 3 — Configurando o Apache para ambos os sites

      Nesta seção, você criará dois arquivos de configuração do host virtual. Isso permitirá que seus dois sites funcionem simultaneamente com duas versões diferentes do PHP.

      Para que o Apache distribua esse conteúdo, é necessário criar um arquivo de host virtual com as diretivas corretas. Em vez de modificar o arquivo de configuração padrão, localizado em /etc/apache2/sites-available/000-default.conf, você criará dois novos arquivos dentro do diretório /etc/apache2/sites-available/.

      Primeiro,crie um novo arquivo de configuração de host virtual para o site site1.your_domain. Aqui, você direcionará o Apache a renderizar o conteúdo usando o php7.0:

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

      Adicione o conteúdo a seguir: Verifique se o caminho do diretório do site, o nome do servidor e a versão de PHP correspondem à sua configuração:

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

      Neste arquivo, você atualizou o DocumentRoot para o seu novo diretório e o ServerAdmin para um e-mail que o administrador do site your_domain pode acessar. Você também atualizou o ServerName, o qual estabelece o domínio base dessa configuração do host virtual, bem como adicionou uma diretiva SetHandler para executar o PHP como um servidor de processos fastCGI.

      Salve e feche o arquivo.

      Em seguida, crie um novo arquivo de configuração de host virtual para o site site2.your_domain. Você especificará este subdomínio para implantar o php7.2:

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

      Adicione o conteúdo a seguir: Novamente, verifique se o caminho do diretório do site, o nome do servidor e a versão PHP correspondem às suas informações únicas:

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

      Salve e feche o arquivo quando você terminar. Em seguida, verifique se há erros de sintaxe no arquivo de configuração do Apache:

      • sudo apachectl configtest

      Você verá o seguinte resultado:

      Output

      Syntax OK

      Agora, habilite ambos os arquivos de configuração de host virtual:

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

      Você não precisará do site padrão. Desabilite-o:

      • sudo a2dissite 000-default.conf

      Finalmente, reinicie o serviço do Apache para implementar suas alterações:

      • sudo systemctl restart apache2

      Após configurar o Apache para atender a cada site, você os testará para garantir que as versões apropriadas do PHP estejam funcionando corretamente.

      Passo 4 — Testando os sites

      Até aqui, você já configurou dois sites para executar duas versões diferentes do PHP. Agora, teste os resultados.

      Abra seu navegador Web e visite os dois sites http://site1.your_domain e http://site2.your_domain. Você verá duas páginas parecidas com estas:

      Página de informações do PHP 7.0Página de informações do PHP 7.2

      Observe os títulos. A primeira página indica que o site1.your_domain implantou o PHP 7.0. A segunda indica que o site2.your_domain implantou o PHP 7.2.

      Agora que você testou seus sites, remova os arquivos info.php. Como eles contêm informações confidenciais sobre seu servidor e estão acessíveis a usuários não autorizados, eles representam uma ameaça à segurança. Para remover os dois arquivos, execute os comandos a seguir:

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

      Agora, você tem um único servidor Ubuntu 18.04 lidando com dois sites, com duas versões diferentes do PHP. No entanto, o PHP-FPM não está limitado a este aplicativo.

      Conclusão

      Você combinou os hosts virtuais e o PHP-FPM para atender vários sites e várias versões do PHP em um único servidor. O único limite prático sobre o número de sites PHP e de versões do PHP que o seu serviço do Apache pode gerenciar é a capacidade de processamento de sua instância.

      A partir daqui, considere explorar recursos mais avançados do PHP-FPM, como sua geração de processos adaptáveis ou a maneira como ele pode acessar o sdtout e o stderr. Como uma alternativa, você pode agora proteger seus sites. Para fazer isso, você pode seguir nosso tutorial sobre como proteger seus sites com certificados TLS/SSL gratuitos do Let’s Encrypt.



      Source link