0

I'm trying to run two websites on the same hostname where one serves static content (an AngularJS application) and the other one routes all requests to PHP (API written using Apigility) but only for a specific path in the URL (more on that later).

At the moment I have two nginx vhosts listening on two different domains, which works just fine, however the client application will eventually be authenticating against the API using OAuth and I don't want to store tokens or any other sensitive data in client's cookies, local storage or anywhere else. This article explains the reasoning behind it better than I could explain myself.

With that problem in mind I've decided to have a "proxy" server, which will by default (important) serve any static content that the client browser requests, however if a request comes in that starts with /api/ then it should be rerouted to php-fpm.

To give you an example, let's assume the API has an endpoint /users. What I want to be able to do is run my AngularJS application as I normally would, e.g. on http://monkey.com/index.html but at the same time if I perform an AJAX request to http://monkey.com/api/users it should forward the /users bit to PHP, which will be installed in a different directory (for the sake of this question assume that AngularJS app is installed in /var/www/website and the API is in /var/www/api.

These are the two configs that I have at the moment and which work as separate websites:

AngularJS application config:

server {
    listen      80;
    server_name monkey.com;

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

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

API config:

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

To avoid confusion I won't post my failed attempts but I can only say that I've tried using root and alias to no avail. I guess my biggest issue is I'm not sure how to extract only the part that comes after /api and forward it to PHP, which, to complicate matters, is in a different directory to $document_root.

I've seen quite a few articles and answers on SO mentioning that having root inside a location entry is not a good idea but I don't think this can be solved without doing it.

I've been fighting with this seemingly simple problem for a while now so I hope that someone can give an example of a config that actually works.

1

After spending a considerable amount of time trying to get a working config I seem to have finally managed to do it.

I can now perform requests to http://monkey.com/some/angular/path or http://monkey.com/api/users and serve both, static content or a PHP site respectively, from the same domain.

In case someone stumbles upon this question, here's the config that I've ended up with:

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

The configuration above strips the /api/ prefix and sets REQUEST_URI to whatever followed it. E.g. if you requested monkey.com/api/users/1 you would end up passing /users/1 to php-fpm.

If you don't need to modify the original request URI in any way and just want to pass the whole request URI to PHP you can simplify (and possibly speed up) the configuration as follows:

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

Now on to setting up a Guzzle project for the proxy website!

0

First things first: This code would not have been possible without 'Andris' and Google and others. Please read his code first and then read this if that fails for you!
Angular or any other service can be served on port 4200 and on default path / For eg: http://example.com/ will run angular.

Any url request like http://example.com/api/index.php will be redirected to the appropriate route removing the '/api' from it. So http://example.com/api/index.php will be treated as http://example.com/index.php

I have just test for this code please respond with your patch and suggestions if any!

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.