====== 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.