7

I have set up an any-domain config on my nginx server - to reduce the amount of work needed when I open a new site/domain. This config allows me to simply create a folder in /usr/share/nginx/sites/ with the name of the domain/subdomain and then it just works.™

server {
    # Catch all domains starting with only "www." and boot them to non "www." domain.
    listen 80;
    server_name ~^www\.(.*)$;
    return 301 $scheme://$1$request_uri;
}

server {
    # Catch all domains that do not start with "www."
    listen 80;
    server_name ~^(?!www\.).+;
    client_max_body_size 20M;

    # Send all requests to the appropriate host
    root /usr/share/nginx/sites/$host;

    index index.html index.htm index.php;
    location / { 
        try_files $uri $uri/ =404;
    }

    recursive_error_pages on;
    error_page 400 /errorpages/error.php?e=400&u=$uri&h=$host&s=$scheme;
    error_page 401 /errorpages/error.php?e=401&u=$uri&h=$host&s=$scheme;
    error_page 403 /errorpages/error.php?e=403&u=$uri&h=$host&s=$scheme;
    error_page 404 /errorpages/error.php?e=404&u=$uri&h=$host&s=$scheme;
    error_page 418 /errorpages/error.php?e=418&u=$uri&h=$host&s=$scheme;
    error_page 500 /errorpages/error.php?e=500&u=$uri&h=$host&s=$scheme;
    error_page 501 /errorpages/error.php?e=501&u=$uri&h=$host&s=$scheme;
    error_page 503 /errorpages/error.php?e=503&u=$uri&h=$host&s=$scheme;
    error_page 504 /errorpages/error.php?e=504&u=$uri&h=$host&s=$scheme;

    location ~ \.(php|html) {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_intercept_errors on;
    }
}

However there is one issue that I'd like to resolve, and that is when a domain that doesn't have a folder in the sites directory, nginx throws an internal 500 error page because it cannot redirect to /errorpages/error.php as it doesn't exist.

How can I create a fallback error page that will catch these failed requests?

2
  • Do the sites have different error.php code or is it the same? May 31, 2013 at 19:35
  • All different, unfortunately Jun 6, 2013 at 13:29

5 Answers 5

0

Below piece of code should solve your issue

  http {
      server {
          error_page 404 http://www.mywebsite.com/error.php;
          error_page 500 http://www.mywebsite.com/error.php;

    }
  ................
  ................
    } 
4
  • The problem with this is that it doesn't allow for custom error pages per domain. May 22, 2013 at 11:34
  • How about using $server_name variable inside a path? For example, error_page 404 $scheme://$server_name/error.php
    – jollyroger
    May 29, 2013 at 18:22
  • Only just seen this comment. Will try. May 31, 2013 at 18:49
  • No, this produces the same result. May 31, 2013 at 18:56
0

May be this will work: (instead of return 404 in last location you can try to specify exact error URL)

location / { 
        try_files $uri $uri/ @notfound;
    }

location @notfound {
  root /usr/share/nginx/sites/errorpages;
  return 404;
}
3
  • This doesn't cover any other errors. May 31, 2013 at 18:49
  • Yes, but how can other errors happen with non-existent $host? i think they all will be 404 Jun 1, 2013 at 21:43
  • For some reason, nginx still attempts to redirect, causing an internal error. Jun 4, 2013 at 9:51
0

I probably need to give this more thought, but what if you try something like:

location /errorpages {
try_files $uri $uri/  @fallback
}

location @fallback {
root /usr/share/nginx/sites/default
... error page directives ...

}

Where the default holds the error pages for non-existent sites.

Basically try to create a conditional root.

See: http://end.re/2011/05/02/nginx-alternative-root-with-conditional-autoindex/

Update

This worked for the 404 case:

location / 
try_files $uri $uri/ @errors;
...
}

location @errors {
try_files $uri $uri/ =510;
root /usr/share/nginx/sites/errors;
error_page 404 = /404.html
}

(You have to create the errors/404.html of course)

4
  • The root change appears to not work - it still causes an internal redirection cycle. Jun 4, 2013 at 9:51
  • I updated my answer with something that may get you partway. Jun 5, 2013 at 19:48
  • It's still ignoring the root change. Jun 6, 2013 at 13:29
  • You may need to pull your error directives from the server block. I don't have time to retest but pretty sure this works without other error directives. Jun 6, 2013 at 15:12
0

Fallback error pages in nginx work like:

error_page 400 /400.html;
location = /400.html {
    try_files /400.html @error;    # <-- this is your missing part 1
    internal;                      # suggested
}
location @error {   # <-- this is your missing part 2
    root /var/www/error;
}
0

Try using an if conditional in your server that handles cases where that website does not exist

server {
    # Catch all domains that do not start with "www."
    listen 80;
    server_name ~^(?!www\.).+;
    client_max_body_size 20M;

    # Send all requests to the appropriate host

    if(!-d /usr/share/nginx/sites/$host){ 
        set $host notexist
    }

    root /usr/share/nginx/sites/$host;

    index index.html index.htm index.php;
    location / { 
        try_files $uri $uri/ =404;
    ...

And add an index.html in the /usr/share/nginx/sites/notexist describing that the site does not exist

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .