Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx with sub locations

I'm trying to setup a dev server with nginx for two projects, one in rails and one in PHP. I want a base URL (dev.example.com) for both projects and a sub location for each one (dev.example.com/rails_proj and dev.example.com/php_proj). My nginx conf is like the following:

server {
    listen 80;
    server_name dev.example.com;

    passenger_enabled on;
    passenger_app_env development;
    passenger_buffer_response off;
    root /var/www/dev;

    location ~ ^/rails_proj {
            root /public;
            passenger_base_uri /rails_proj;
            passenger_app_root /var/www/dev/rails_proj;
            passenger_document_root /var/www/dev/rails_proj/public;
    }

    location ~ ^/php_proj {
            root /web;
            try_files $uri /app_dev.php$is_args$args;

            location ~ \.php(/|$) {
                    fastcgi_pass unix:/var/run/php5-fpm.sock;
                    fastcgi_split_path_info ^(.+\.php)(/.*)$;
                    include fastcgi_params;
                    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            }
    }
}

The rails project works fine but the PHP project gives me an "file not found" when I try to access dev.example.com/php_proj/app_dev.php and in the log It says: FastCGI sent in stderr: "Primary script unknown". I found issues related to It and I've tried a number of ways but I can't come up with something that works for both projects. How can I fix this?

like image 236
Alexandre Bonicelli Avatar asked Oct 30 '22 23:10

Alexandre Bonicelli


2 Answers

It might be easier to manage as two server blocks with an extra subdomain for each. It also reduces potential confusion introduced by multiple regex locations:

server {
    server_name rails.dev.example.com;
    return 200 "Hello from rails app.
";
}

server {
    server_name php.dev.example.com;
    return 200 "Hello from php app.
";
}
like image 174
Cole Tierney Avatar answered Nov 04 '22 07:11

Cole Tierney


I'm sure you've moved on or figured this out by now, but for posterity's sake: the root directive in your location block overrides your server root directive. It's not relative to it. The way you have your conf, the project files would need to be located in the absolute path /web/php_proj on your web server.

I can't quite determine the way your local paths are set up, but if /var/www/dev/rails_proj/public is the directory that contains your app root, you may instead need to do something like this:

location /rails_proj {
    alias /var/www/dev/rails_proj/public;
}

Using alias instead of root will strip the /rails_proj from the beginning of the request path and serve files relative to the alias path. For example, if you request http://dev.example.com/rails_proj/php/test.php, it will serve the file /var/www/dev/rails_proj/public/php/test.php

Also, I would definitely recommend changing your top level location paths from regex to standard prefix paths. location ~ ^/php_proj is effectively identical to location /php_proj except that using regex messes with the way nginx decides what location to serve. Regex paths are more performance intensive, act on a first-match basis rather than best match, and will take priority over all prefix path locations.

Another thing to note: using $document_root$fastcgi_script_name may not always work as expected. Especially if using the alias directive instead of root. Using the variable $request_filename instead is preferable in most cases.

like image 23
Joshua Timmer Avatar answered Nov 04 '22 09:11

Joshua Timmer