通过 nginx 为 URL 中的特定路径提供 php-fpm 服务,默认为静态内容

通过 nginx 为 URL 中的特定路径提供 php-fpm 服务,默认为静态内容

我试图在同一个主机名上运行两个网站,其中一个提供静态内容(AngularJS 应用程序),另一个将所有请求路由到 PHP(使用 Apigility 编写的 API),但仅针对 URL 中的特定路径(稍后会详细介绍)。

目前,我有两个 nginx vhost 在两个不同的域上监听,它们工作得很好,但是客户端应用程序最终将使用 OAuth 对 API 进行身份验证,并且我不想在客户端的 cookie、本地存储或任何其他地方存储令牌或任何其他敏感数据。本文比我自己能解释的更好地解释了其背后的原因。

考虑到这个问题,我决定使用一个“代理”服务器,它将默认(重要)提供客户端浏览器请求的任何静态内容,但是如果收到以 开头的请求,/api/则应将其重新路由到 php-fpm。

举个例子,假设 API 有一个端点/users。我想要做的是像平常一样运行我的 AngularJS 应用程序,例如,http://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;
    }
}

为了避免混淆,我不会发布我失败的尝试,但我只能说我尝试过使用root,但alias无济于事。我想我最大的问题是我不确定如何只提取后面的部分/api并将其转发到 PHP,而 PHP 位于与$document_root

我已经看到很多文章和答案,其中提到在条目root内部添加location不是一个好主意,但我认为不这样做就无法解决这个问题。

我已经为这个看似简单的问题奋斗了一段时间,所以我希望有人能给出一个真正有效的配置示例。

答案1

在花费了大量时间尝试获取可行的配置后,我似乎终于成功了。

我现在可以从同一个域执行请求http://monkey.com/some/angular/pathhttp://monkey.com/api/users分别提供静态内容或 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;

        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;
    }
}

现在开始设置狂饮代理网站的项目!

答案2

首先要做的事情:如果没有“Andris”和 Google 以及其他人的努力,这个代码就不可能实现。请阅读他的代码首先,如果失败了,请阅读此内容!
Angular 或任何其他服务都可以在端口 4200 和默认路径上提供服务 / 例如:http://example.com/将运行角度。

任何 URL 请求,例如http://example.com/api/index.php将被重定向到适当的路由,并从中删除“/api”。因此http://example.com/api/index.php将被视为http://example.com/index.php

我刚刚测试了此代码,如果有任何补丁和建议,请回复!

 server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  localhost;
        #root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
           proxy_pass http://127.0.0.1:4200;
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection 'upgrade';
           proxy_set_header Host $host;
           proxy_cache_bypass $http_upgrade;

        }
        location /api/ {
            root /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   127.0.0.1:9000;
            fastcgi_index  index.php;

        include fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root$path;
            fastcgi_param REQUEST_URI   $path;
           # index  index.php index.html index.htm;
        }
    }

相关内容