Múltiplas versões de PHP através do nginx

Múltiplas versões de PHP através do nginx

EDITAR:Para referência futura

Estou executando o Ubuntu 14.10 com uma pilha LEMP usando PHP 5.5.12. Tenho vários sites WordPress legados que exigem PHP 5.3.3 junto com alguns sites WP que usam uma versão bastante recente do PHP, todos rodando em nginxna minha máquina local.

Minhas mãos estão atadas em relação a máquinas virtuais e sandboxes, tudo que posso brincar é com nginx, daí esta pergunta. Entendo as preocupações de segurança das pessoas, mas preciso que esses sites sejam executados localmente para que eu possa testar recursos quebrados à medida que os atualizo para as versões mais recentes do PHP/WP.

Quero que o nginx execute a versão correta do PHP (usando php-fpm) dependendo do site WordPress. De acordo comoutroPergunta SF, uma maneira de conseguir isso é ter as diferentes versões do PHP rodando em portas/soquetes separados e configurar os blocos do servidor nginx para usar a respectiva porta/soquete.

Compilei o PHP 5.3.3 manualmente para incluir o php-fpm, mas isso é o mais longe que consegui.

Efetivamente, quero que alguém explique com um pouco mais de detalhesesseresponder. Eu não consigo descobrir como"execute cada versão do php-fpm em uma porta (ou soquete) diferente"ou"configure a porta apropriada em seu parâmetro fastcgi_pass em seu bloco de servidor nginx".

Um dos meus blocos de servidor se parece com este para referência

server {
    listen 80;
    listen [::]:80;

    root /usr/share/nginx/html/testsite1;
    index index.php index.html index.htm;

    server_name local.testsite1.com;

    location / {
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }

    error_page 404 /404.html;

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}

EDITAR:

Eu configurei cada site usando um bloco de servidor separado em um arquivo separado, vinculado simbolicamente entre /var/nginx/sites-available/testsite1e /var/nginx/sites-enabled/testsite1. Então var/nginx/sites-availablecontém;

 testsite1
 testsite2
 testsite3
 ...

EntãoidealmenteEu queria saber se algo como o que está abaixo é possível (já que isso é semelhante a como o Apache pode ser configurado com diferentes versões do PHP)

testsite1 - executando uma versão mais antiga do PHP

 server {
    listen 80;
    listen [::]:80;

    root /usr/share/nginx/html/testsite1;
    index index.php index.html index.htm;

    server_name local.testsite1.com;

    ...settings to use older PHP version...

    ...remaining nginx settings...
}

testsite2 - executando a versão atual do PHP

 server {
    listen 80;
    listen [::]:80;

    root /usr/share/nginx/html/testsite2;
    index index.php index.html index.htm;

    server_name local.testsite2.com;

    ...settings to use currrent PHP version (if needed)...

    ...remaining nginx settings...
}

Isso é possível? A razão pela qual pergunto é que prefiro evitar renomear todos os meus phparquivos para php2serem executados (tornando o controle de versão um problema). Não me importo de editar o nginx.confarquivo ou quaisquer etapas necessárias, desde que não precise renomear os arquivos.

eu tambémacreditarPreciso usar soquetes (fastcgi_pass unix:/var/run/php5-fpm.sock;)em portas devido ao WordPress (embora esteja aberto a todas as sugestões).

Responder1

Ok, você deseja executar várias versões do PHP por meio do nginx, o arquivo de configuração deve incluir o caminho específico onde você coloca seus scripts PHP em uma versão ou nome de extensão diferente.

No entanto, gostaria de explicar o link da pergunta SF fornecido em sua postagem.

Essa resposta oferece uma maneira de modificar o confseu nginx, o que pressupõe que o questionador tenha experiência em nginx.

Ao fornecer uma porta específica conf, o nginx fará com que o script seja executado através desse canal FastCGI.

Vamos fingir que você instalou uma versão diferente do PHP em seu servidor e modificou o portarquivo php-fpm.conf.

Você deseja que todos phpos arquivos sejam executados em versão 5.5.0e php2arquivos executados em 5.6.0.

Exemplo de configuração do nginx como segue,

    listen       8080;
    server_name  localhost;

    root   html;

    location / {
        index  index.php index.php2;
    }

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  "${document_root}${fastcgi_script_name}";
        include        fastcgi_params;
    }

    location ~ \.php2$ {
        fastcgi_pass   127.0.0.1:9001;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  "${document_root}${fastcgi_script_name}";
        include        fastcgi_params;
    }

Neste caso, phpé processado pela porta 9000e php2vai para9001

Este é apenas um exemplo simples, para avançados você pode criar duas pastas diferentes para armazenar arquivos php, por exemplo, /home/php55e /home/php56, em seguida, editar seu arquivo nginx.conf.

PARA SUA PERGUNTA EDITADA

Se você quiser tentar adicionar servidores diferentes para processar os scripts em versões diferentes, claro que pode fazer isso, porque o nginx pode ser um balanceador de carga, ele também pode lidar com esse tipo de problema.

Primeira aplicação

server{
listen 80;
server_name php1.localhost; 

root   /home/www/php5.5;

location / {
  index  index.php;
}

location ~ \.php$ {
  fastcgi_pass   127.0.0.1:9002; (You can change it to your private IP in the future)
  fastcgi_index  index.php;
  fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  include        fastcgi_params;
}
}

Segunda aplicação

server{
listen 80;
server_name php2.localhost; 

root   /home/www/php5.6;

location / {
  index  index.php;
}

location ~ \.php$ {
  fastcgi_pass   127.0.0.1:9004; (You can change it to your private IP in the future)
  fastcgi_index  index.php;
  fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  include        fastcgi_params;
}
}

Usando a configuração acima, você pode facilmente alternar o resultado da versão diferente do script PHP, além disso, você pode usar NFS (se estiver em um ambiente *nix) para montar o disco, neste caso, você não precisará colocar arquivos em duas pastas manualmente.

Quanto ao método de passagem Fastcgi, sugiro usar PORT em vez de Socket.

Todos nós sabemos que o Unix Socket tem um melhor desempenho porque a porta TCP usa toda a pilha da rede, mesmo na mesma máquina.

Porém, o tempo que você economiza é muito pouco, além disso, você pode enfrentar esse problema ao usar o Socket em um horário de alto tráfego,

connect() para unix:/var/run/php5-fpm.sock falhou ouapr_socket_recv: Conexão redefinida por peer (104)

Além disso, a porta TCP pode fornecer uma maneira mais rápida de gerenciar se você colocar nginx e php-fpm em servidores separados.

Estou usando um laptop pequeno para editar este post, então os códigos não são bonitos, mas tentei....

EDITADO

Lembre-se de modificar o seu /etc/hostspara corresponder ao seu nome de host (server_name in nginx.conf)

Responder2

Para fins de teste, eu queria configurar meu nginx para usar diferentes versões do php em diferentes locais na mesma seção do servidor. Finalmente funcionou com isso:

#Folder to run some tests with the new php-7
location ~ "^\/test_php7.0.3\/.*\.php$" {
    try_files $uri =404;
    fastcgi_pass unix:/var/run/php7-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

#Folder to run some tests with a custom compiled version of php5.6
location ~ "^\/test_php5.6.18\/.*\.php$" {
    try_files $uri =404;
    fastcgi_pass unix:/var/run/php56-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

#The default php version:
location ~ \.php$ {
    try_files $uri =404;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Espero que isso ajude outra pessoa :)

informação relacionada