Nginx

通過 nginx 為預設為靜態內容的 URL 中的特定路徑提供 php-fpm

  • June 5, 2018

我正在嘗試在同一主機名上執行兩個網站,其中一個提供靜態內容(AngularJS 應用程序),另一個將所有請求路由到 PHP(使用 Apigility 編寫的 API),但僅針對 URL 中的特定路徑(更多資訊)之後)。

目前我有兩個 nginx 虛擬主機在兩個不同的域上監聽,這工作得很好,但是客戶端應用程序最終將使用 OAuth 對 API 進行身份驗證,我不想在客戶端的 cookie 中儲存令牌或任何其他敏感數據,本地儲存或其他任何地方。這篇文章比我自己解釋的更好地解釋了它背後的原因。

考慮到這個問題,我決定有一個“代理”伺服器,預設情況下(重要)它將提供客戶端瀏覽器請求的任何靜態內容,但是如果一個請求以它開頭,/api/那麼它應該重新路由到 php -fpm。

舉個例子,假設 API 有一個端點/users。我想要做的是像往常一樣執行我的 AngularJS 應用程序,例如 onhttp://monkey.com/index.html但同時如果我對它執行 AJAX 請求,http://monkey.com/api/users應該將/users位轉發給 PHP,它將安裝在不同的目錄中(對於為了這個問題,假設 AngularJS 應用程序安裝在/var/www/website並且 API 在/var/www/api.

這些是我目前擁有的兩個配置,它們作為單獨的網站工作:

AngularJS 應用程序配置:

server {
   listen      80;
   server_name monkey.com;

   root        /var/www/website;
   index       index.html

   location / {
       try_files $uri $uri/ /index.html =404;
   }
}

API 配置:

server {
   listen      80;
   server_name api.monkey.com;

   root        /var/www/api/public;
   index       index.php

   include     /etc/nginx/fcgiwrap.conf;

   location / {
       try_files $uri $uri/ /index.php$is_args$args;
   }

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

為避免混淆,我不會發布我失敗的嘗試,但我只能說我嘗試過使用rootalias無濟於事。我想我最大的問題是我不確定如何僅提取後面的部分/api並將其轉發給 PHP,更複雜的是,它位於與*$document_root*不同的目錄中。

我已經看過很多關於 SO 的文章和答案提到rootlocation條目中包含不是一個好主意,但我認為不這樣做就無法解決。

我一直在與這個看似簡單的問題作鬥爭一段時間,所以我希望有人可以舉一個實際有效的配置範例。

在花了相當多的時間試圖獲得一個工作配置之後,我似乎終於設法做到了。

我現在可以分別從同一個域執行對靜態內容或 PHP 站點的請求http://monkey.com/some/angular/path或同時提供這兩者。http://monkey.com/api/users

如果有人偶然發現這個問題,這是我最終得到的配置:

server {
   listen      80;
   server_name monkey.com;

   location / {
       alias     /var/www/website/;
       try_files $uri $uri/ /index.html =404;
   }

   location /api/ {
       alias     /var/www/api/public;
       try_files /index.php =404;

       set $path $request_uri;
       if ($request_uri ~ ^/api/(.*)$ ) {
           set $path /$1;
       }

       fastcgi_split_path_info ^(.+\.php)(/.+)$;
       fastcgi_pass            unix:/var/run/php5-fpm.sock;
       fastcgi_index           index.php;

       include fastcgi_params;
       fastcgi_param SCRIPT_FILENAME $document_root/index.php;
       fastcgi_param REQUEST_URI     $path;                                                                                                                                                                                                                                        
   }
}

上面的配置去掉了/api/前綴並設置REQUEST_URI為它後面的任何內容。例如,如果您要求monkey.com/api/users/1,您最終會傳遞/users/1給 php-fpm。

如果您不需要以任何方式修改原始請求 URI,而只想將整個請求 URI 傳遞給 PHP,您可以簡化(並可能加快)配置,如下所示:

server {
   listen      80;
   server_name monkey.com;

   location / {
       alias     /var/www/website/;
       try_files $uri $uri/ /index.html =404;
   }

   location /api/ {
       alias     /var/www/api/public;
       try_files /index.php =404;

       fastcgi_split_path_info ^(.+\.php)(/.+)$;
       fastcgi_pass            unix:/var/run/php5-fpm.sock;
       fastcgi_index           index.php;

       include fastcgi_params;
       fastcgi_param SCRIPT_FILENAME $document_root/index.php;
   }
}

現在開始為代理網站設置Guzzle項目!

引用自:https://serverfault.com/questions/721292