Using nginx with dockerized fast cgi - root path

I have a docker container that runs a php fastcgi application on port 9000.

The root path is mounted at /var/www/my_app and contains all assets like images and javascript.

I want to use nginx as a reverse proxy. My current nginx configuration file looks like this:

server {
  listen 80;
  server_name my_app.example.org;

  root /var/www/my_app;
  index index.php index.html index.htm;

  location / {
    try_files $uri $uri/ =404;
  }

  location ~ \.php$ {
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx;
    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;
    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_pass my_app_upstream; 
    include fastcgi_params;
  }
}

Unfortunately this is not working. I receive 404 errors for all sites/resources.

I was able to fix this by changing the config file to this:

server {
  (...)

  root /var/www/html;                       #changed
  index index.php index.html index.htm;

  location / {
    root /var/www/my_app/;                  #changed
  }

  (...)

}

Why does it behave so strange? And is the second approach secure?


Solution 1:

So your upstream has a different root path to the same files. What you are doing is setting the root to /var/www/my_app/ for static files (served by the nginx instance) and setting $document_root to /var/www/html for the FastCGI instance.

You say it is working, so your static files must be available under /var/www/my_app/ and your PHP files must be available under /var/www/html.

It would probably make more sense to structure it like this:

server {
    ...
    root /var/www/my_app;

    location / {
        ...
    }
    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;

        fastcgi_param  SCRIPT_FILENAME  /var/www/html$fastcgi_script_name;
        root /var/www/html;
    }
}

The special root for FastCGI is hardwired, but not before the presence of the files are checked with a try_files to avoid Passing Uncontrolled Requests to PHP.