20

I migrated from Apache 2 to nginx and I've got problems to handly my subdomain control. What I want: When x.domain.tld is requested, internally rewrite to domain.tld/x

The problem I've got is that nginx always redirects the page by telling the browser to redirect to. But what I really want is to do this internally, like Apache 2 did. Also, if I only request x.domain.tld, nginx returns a 404. It only works when I do x.domain.tld/index.php

Here's my config:

server {
        listen      80 default;
        server_name _ domain.tld www.domain.tld ~^(?<sub>.+)\.domain\.tld$;

        root /home/domain/docs/;

        if ($sub) {
                rewrite (.*) /$sub;
        }

        # HIDDEN FILES AND FOLDERS
        rewrite ^(.*)\/\.(.*)$ @404 break;

        location = @404 {
                return 404;
        }

        # PHP
        location ~ ^(.*)\.php$ {
                if (!-f $request_filename) {
                        return 404;
                }

                include       /etc/nginx/fastcgi_params;
                fastcgi_pass  unix:/etc/nginx/sockets/domain.socket;
        }
}

Thanks!

4 Answers 4

12

As I found this Q&A on Google while looking for a solution for the same problem, I wanted to post the solution I finally used.


The first server block by MTeck looks pretty nice, but for the subdomains part you could simply do the following:

server {
  listen 80;
  server_name "~^(?<sub>.+)\.domain\.tld$";

  root /path/to/document/root/$sub;

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

  location ~ \.php {
    include fastcgi_params;
    fastcgi_pass  unix:/etc/nginx/sockets/domain.socket;
  }
}

This makes the root configuration directive dependent on the subdomain.

Sign up to request clarification or add additional context in comments.

Comments

4

I spent hours beating my head against the wall and this is what works for me

server {
    listen       80;

    server_name ~^(?P<sub>.+)\.example\.com$; #<-- Note P before sub, it was critical for my nginx
    root /var/www/$sub; #<-- most important line cause it defines $document_root for SCRIPT_FILENAME

    location / {
            index index.php index.html; #<-- try_files didn't work as well
    }

    location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000; #<-- probably you have another option here e.g. fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index  index.php;
            fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
            include        fastcgi_params;
    }
}

4 Comments

It works for me also, thank you. Do you know how I can add support for www, some exception? Right now when try to use www.mydomain.com it try try use sub domain.
Also seems it will not works with wordpress as wp requires /index.php?$args
@fdrv you have to put your own rules in location / { ... } section, e.g.: rewrite ^(.*?)$ /index.php?rt=$1 last; works
Note: The "P" stands for Python compatible syntax, which might be required if the PCRE library is too old to support named groups. ( Reference: nginx.org/en/docs/http/server_names.html#regex_names )
0

You should take a look at http://wiki.nginx.org/IfIsEvil. You're doing a whole lot wrong in this configuration file.

server {
    server_name domain.tld www.domain.tld;

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

    location ~ \.php {
        include fastcgi_params;
        fastcgi_pass  unix:/etc/nginx/sockets/domain.socket;
    }
}

server {
    server_name "~^(?<sub>.+)*\.(?<domain>.*)$";
    return 301 $scheme://$domain/$sub$request_uri;
}

If what you want is to keep that internal, you won't be able to rewrite it. By definition, a cross site rewrite needs to be sent back to the browser. You'll have to proxy the request.

server {
    server_name "~^(?<sub>.+)*\.(?<domain>.*)$";
    proxy_pass http://$domain/$sub$request_uri;
}

You should read the Nginx wiki. All of this is explained in depth.

2 Comments

trying to restart nginx with your example causes error failed: unrecognized character after (?<
I have to mention it was nginx 1.10.1
0

This will work for www also.

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    index index.php index.html index.htm index.nginx-debian.html;
    server_name ~^www\.(?P<sub>.+)\.domain\.com$ ~^(?P<sub>.+)\.domain\.com$;
    root /var/www/html/$sub;

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.