====== Nginx com PHP-FPM para framework Laravel ======
===== Objetivo =====
Essta página visa apresentar a configuração correta para configurar o PHP-FPM juntamente com o framework Laravel nos moldes como são desenvolvidas as aplicações pela InfoTIC.
===== Arquitetura de programação =====
Os novos sistemas desenvolvidos pela InfoTIC possuem uma separação de camadas. A primeira camada é a de apresentação, geralmente desenvolvido com o framework AngularJS. A segunda camada é a API do sistema, que pode ser desenvolvida em qualquer linguagem de programação e/ou frameworks.
O acesso a API é feito através de funções javascript existentes na camada de apresentação. A API então retorna o resultado para apresentação em tela.
A padronização que estamos adotando para esta configuração é a seguinte:
- **url.ufrj.br/** : Endereço para acessar a camada de aplicação (interface do usuário).
- **url.ufrj.br/api** : Endereço para acessar a API desta aplicação.
A figura abaixo mostra como funciona a distribuição da API pelo Nginx, inclusive com possibilidade de balanceamento de carga.
{{ :nginx:php-fpm:php-fpm.png?700 }}
==== Definição de diretórios ====
Os diretórios do programa desenvolvido estão organizados, no servidor web, da seguinte forma:
- /var/www --> Aplicação
- /var/www/api --> Diretório da API, que pode ser um apontamento, link simbólico ou local físico.
No servidor php, todos os arquivos estão dentro do diretório **/var/www**.
===== Arquivo de configuração =====
Aqui apresento apenas os arquivos de configuração do virtual host e do php-fpm.
As configurações básicas do nginx não estão descritas nesta página.
==== PHP-FPM: www.conf ====
Temos que definir primeiramente a porta que o php escutará no servidor. Por padrão estamos usando a porta 9000, mas qualquer outra pode ser usada.
listen = 9000
Depois disso precisamos dizer com qual usuário o deamon do php-fpm executará.
user = www-data
group = www-data
O próximo passo é a definição das diretivas do pool. Estamos usando o valor padrão nos servidores:
pm = dynamic
pm.max_children = 6
pm.start_servers = 3
pm.min_spare_servers = 3
pm.max_spare_servers = 5
pm.max_requests = 500
pm.status_path = /fpm-status-zwei
ing.path = /ping-zwei
request_terminate_timeout = 120s
request_slowlog_timeout = 5s
slowlog = /var/log/$pool.log.slow
rlimit_files = 4096
rlimit_core = 0
catch_workers_output = yes
Precisamos definir em qual diretório o php-fpm interpretará os arquivos php. Adotamos como padrão executar os arquivos no diretório /var/www.
chdir = /var/www
Por fim, definimos o timezone.
php_admin_value[date.timezone] = America/Sao_Paulo
==== Nginx: vhos.conf ====
O arquivo de configuração do nginx possui algumas características próprias para configurar a api. Descreverei abaixo cada uma delas e o porquê de serem feitas desta forma.
Iniciamos pelo root da aplicação. Apesar de estarmos tratando da API, o nginx processará todas as páginas, tando da inteface quanto API. Por este motivo o root da aplicação deve ser o diretório /var/www.
root /var/www;
# Localização básica do website.
location /{
index index.html;
}
O próximo passo é fazer com que o nginx encaminhe todas as requisições da API para o servidor PHP-FPM.
location /api {
alias /var/www/api/public;
try_files $uri $uri/ @api;
}
# Reescrita da URL usando o caminho correto (alias) da uri /api.
location @api{
rewrite ^/api/(.*)$ /api/public/index.php?$1 last; # THIS IS THE IMPORTANT LINE
}
Aqui cabe uma observação: precisamos criar uma localização funcional chamada **@api**, pois sem ela o nginx não envia corretamente a informação ao servidor PHP.
Outra observação necessária é que o location tem que ser em **/api**, sem o til, pois de outra forma o arquivo é enviado para o servidor php, mas em diretório absoluto, o que gera o erro de arquivo não encontrado.
Apesar da presença do comando **try_files**, nem todos os arquivos são ignorados. A solução foi forçar a área de exclusão do nginx:
# Esta diretiva faz com que o php não processe arquivos de website.
location ~* \.(jpg|jpeg|gif|css|png|js|ico|html|pdf)$ {
access_log off;
expires max;
log_not_found off;
}
O próximo passo é informar o servidor do PHP-FPM para processamento.
# Diretivas do PHP-FPM
location ~ \.php(?:$|/) {
fastcgi_pass phpfpm:9000;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
Aqui estou usando o nome phpfpm ao invés do IP. Isso é útil caso eu queira, no futuro, criar um sistema de balanceamento de carga pro meu serviço da API.