13

I am trying to setup my development nginx/PHP server with a basic master/catch-all vhost config so that I can created unlimited ___.framework.loc domains as needed.

server {
        listen 80;
        index index.html index.htm index.php;

        # Test 1
        server_name ~^(.+)\.frameworks\.loc$;
        set $file_path $1;
        root    /var/www/frameworks/$file_path/public;

        include /etc/nginx/php.conf;
}

However, nginx responds with a 404 error for this setup. I know nginx and PHP are working and have permission because the localhost config I'm using works fine.

server {
        listen 80 default;
        server_name localhost;
        root /var/www/localhost;
        index index.html index.htm index.php;

        include /etc/nginx/php.conf;
}

What should I be checking to find the problem? Here is a copy of that php.conf they are both loading.

location / {
        try_files $uri $uri/ /index.php$is_args$args;
}

location ~ \.php$ {

        try_files $uri =404;

        include fastcgi_params;
        fastcgi_index index.php;

        # Keep these parameters for compatibility with old PHP scripts using them.
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        # Some default config
        fastcgi_connect_timeout        20;
        fastcgi_send_timeout          180;
        fastcgi_read_timeout          180;
        fastcgi_buffer_size          128k;
        fastcgi_buffers            4 256k;
        fastcgi_busy_buffers_size    256k;
        fastcgi_temp_file_write_size 256k;
        fastcgi_intercept_errors    on;
        fastcgi_ignore_client_abort off;
        fastcgi_pass 127.0.0.1:9000;

}
Xeoncross
  • 4,269
  • 12
  • 42
  • 55

5 Answers5

14

Nginx config is not a program, it's a declaration. When you are using config like this:

server {
        server_name ~^(.+)\.frameworks\.loc$;
        ...
        set $file_path $1;
        root    /var/www/frameworks/$file_path/public;
}

There's no way to ensure that your set directive will execute before root.

But there's a trick with map directive I like to use. It relies on fact that map is evaluated before location

http {
  map $http_host $rootpath {
    ~^(.?<mypath>+)\.frameworks\.loc$  $mypath;
    default                            /      ;
  }
  ....
  root /var/www/frameworks/$rootpath
}
DukeLion
  • 3,239
  • 1
  • 17
  • 19
12

Why not just use:

server_name *.frameworks.loc;
root /var/www/frameworks/$http_host/public;
Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
4

In addition to great DukeLion's answer, I needed to change line

~^(.?<mypath>+)\.frameworks\.loc$ $mypath;

to

~^(?P<mypath>.+)\.frameworks\.loc$ $mypath;

in my /etc/nginx/nginx.conf file as suggested here.

Adding

root /var/www/frameworks/$rootpath

in /etc/nginx/sites-available/default worked fine after that.

zub0r
  • 141
  • 2
0

Maybe you can look into lighttpd also. It has build in support for exactly what you are asking here. It is call mod_evhost.

Enable evhost

Add following lines into your lighttpd.conf. If you are using Debian/Ubuntu base distribution, just soft link or copy from /etc/lighttpd/conf-available/10-evhost.conf to /etc/lighttpd/conf-enabled/.

    # http://redmine.lighttpd.net/wiki/1/Docs:ModEVhost
    server.modules += ( "mod_evhost" )
    evhost.path-pattern = "/home/www/%_"

The %_ (wildcard) in evhost.path-patten means use the full domain name (eg. www.example.com). A request for www.example.com will automatically direct to document-root /home/www/www.example.com/.

Adding additional site is as easy as creating another directory under /home/www with full domain name. No change to Lighttpd config file.

There are other wildcards and can be used to build directory structure. They are as follow

    %% => % sign
    %0 => domain name + tld
    %1 => tld
    %2 => domain name without tld
    %3 => subdomain 1 name
    %4 => subdomain 2 name
    %_ => full domain name

Detail information is here.

PS: Enabling PHP is also easy if you are on debian/ubuntu platform. Just enable 10-fastcgi.conf and 15-fastcgi-php.conf.

John Siu
  • 3,577
  • 2
  • 15
  • 23
0

NGINX uses the PCRE regular expression library.
As of NGINX v0.8.25 server_name directive allows named captures.

Named captures in regular expressions create variables (0.8.25) that can later be used in other directives While using named parenthesis, NGINX automatically sets a variable for each named parenthesis, during server names evaluation (I guess).

I use the following snippet to "fence" developers environments. «user» refers to their username and «proj» the project they work on:

# ...
server_name ~^(?<user>[^.]+)\.(?<proj>[^.]+).dev.local-server.com;
root /home/$user/www/$proj;
# ...

Note that nginx configuration is declarative, and as such, static declarations might always be faster compared to run-time calculated values and variables. Regular expressions evaluation is relatively costly, I guess it has to be used with parsimony in heavy loaded (production) environments.

Stphane
  • 111
  • 6