3

I have two applications: HTML+JS frontend and PHP backend. I would like to set Nginx up so that both are served from the same domain. Requests to the backend are made uing URLs starting with /api.

My attempt was this:

server {
    root /path/to/frontend;
    index index.html;
    server_name example.com;

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

    location /api {
        alias /path/to/backend;
        index index.php;
        try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
    }
}

However, for all requests to the backend, I end up with a 404: primary script unknown.

Is there a way to achieve what I'm trying to do here? How?

mingos
  • 157
  • 2
  • 8

1 Answers1

3

You made the usual mistake of people not really understand how nginx works. Remember the following:

nginx always serves a request with a single location block only.

I suggest you (re)read the following: How nginx processes a request

Now, looking at your configuration, backend requests would need to be served by 2 locations:

  1. location /api
  2. location ~\.php$

Following location documentation, the first on is called a prefix location, while the second one is a regular expression (regex) one. nginx will check both but will eventually only select one, which in your case is the regex one.

Now, when processing it, nginx will forward a request for /path/to/frontend/<yourFile>.php to PHP, building the path from root /path/to/frontend, since it is the only one defined. The backend then fails, unable to find the specified file.

You might wish to try the following:

location /api {
    alias /path/to/backend;
    index index.php;
    try_files $uri $uri/ /index.php;

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;

        # Useless? Request always ending up with '.php' here...
        fastcgi_index index.php;

        include fastcgi_params;

        # Try to secure this block, which might lead to arbitrary code execution.
    }
}

As for the lack of security, I hosted a talk about nginx and PHP-FPM at nginx.conf 2014 end October. Slides are available: https://rosset.net/LAMP_just_died.pptx. Video soon available.

Bernard Rosset
  • 1,373
  • 12
  • 25