1

I have a server successfully hosting a number of domains using nginx. Each domain has a separate nginx configuration file.

One domain, let's call it example.com is the default server

It has a config file like so:

# config file for example.com
#
#redirects all www to NON-www
#

server {
    listen 80;
    server_name www.example.com;
    return 301 $scheme://example.com$request_uri;
    }

server {
    listen 80 default_server;
    server_name example.com;
    charset utf-8;
    root /blah/example.com/public/www;

This works great -- until I add a second config file for various "administrative redirects" for folders and subdomains of the same domain.

I did this because this domain is quite old and had a bunch of apps and sites in subdirectories before domains were purchased for those. On the off chance some users have old bookmarks, we want to make sure those still work.

I would like to maintain these redirects in a separate nginx config file for easier oversight.

So here's the second config file (simplified for purposes of discussion):

# config file for Administrative_Redirects.example.com
#redirects Webmin and/or Panel request to proper port and https
#

server {
    listen 80;
    server_name webmin.example.com;
    return https://webmin.example.com:10000;
    }

server {
    listen 80;
    server_name panel.example.com;
    return https://webmin.example.com:10000;
    }


#------------------------------------------------------------------------
#
#redirects all Webmail and related cPanel requests to XYZ account
#

server {
    listen 80;
    server_name webmail.example.com;
    return https://3rdPartyMail.com:port;
    }

server {
    listen 80;
    server_name www.webmail.example.com;
    return https://3rdPartyMail.com:port;
    }


server {
    listen 80;
    server_name cpanel.example.com;
    return https://AnotherDomain.com:port;
    }


#------------------------------------------------------------------------
#
#redirects subdirs to proper domains and/or subdomains
#

# ~*/(regex_case-INSensitive)

server {
    listen 80;
    server_name example.com;

    # some_app
    location ~*/(some_folder)
        {
        return 301 $scheme://SomeOtherDomain.com;
        }

    # another_app
    location ~*/(another_folder)
        {
        return 301 $scheme://AnotherDomain.com;
        }

    # Some_Name
    location ~*/(some_name)
        {
        return 301 $scheme://some_name.example.com;
        }

    }


# strip www subdomain

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

    # some_app
    location ~*/(some_folder)
        {
        return 301 $scheme://SomeOtherDomain.com;
        }

    # another_app
    location ~*/(another_folder)
        {
        return 301 $scheme://AnotherDomain.com;
        }

    # Some_Name
    location ~*/(some_name)
        {
        return 301 $scheme://some_name.example.com;
        }
    }

# -----------

My two problems:

  1. IF this config file for "Administrative_Redirects.example.com" is active, everything within it resolves fine, BUT browsing to example.com or www.example.com result in 404.

  2. Browsing to any_made-up_subdomain.example.com (i.e. anything NOT specified in config file for "Administrative_Redirects.example.com") serves the document root (i.e. root /blah/example.com/public/www; ) . . . but should probably result in 404

The problem seems to come from the following sections in the config file for "Administrative_Redirects.example.com"

#-------
server {
    listen 80;
    server_name example.com;
#-------

and

#-------
server {
    listen 80;
    server_name www.example.com;
#-------

These seem to "preempt" the default_server config file which alpha-sorts later in the list of active nginx sites.

How can I keep the "Administrative_Redirects.example.com" from trampling on the default_server nginx config file?

Is there a better way of doing this while maintaining the redirects in a separate file?

Can I, for example, include these "administrative redirects" into the default_server config file so I wouldn't have such a huge mess there?

Thanks in advance for any insights!

  • Funny, by asking the question in significantly greater detail than I searched, I was just inspired to find serverfault.com/questions/618889/… this may inspire a solution (I'll try tomorrow), but your insights on the optimal answer would still be appreciated – FBachofner Oct 19 '17 at 8:39
  • 1
    If you have two server blocks with the same listen port and server_name, nginx should give you an error or a warning - and at best will ignore one of the server blocks altogether. – Richard Smith Oct 19 '17 at 9:00
  • Thanks Richard. Strangely, nginx didn't seem to throw any errors recorded in any of the logs I looked at. Perhaps I need to look at a system-level log as opposed to an nginx log . . . ? – FBachofner Oct 20 '17 at 8:03
0

You should be using an include directive in the main file to include the redirects file.

Main File for example.com

...

server {
    listen 80 default_server;
    server_name example.com;
    charset utf-8;
    root /blah/example.com/public/www;

    # add this line
    include redirects.conf;
}

Then put all the redirects without a server block into redirects.conf:

# some_app
location ~*/(some_folder) {
    return 301 $scheme://SomeOtherDomain.com;
}

# another_app location ~*/(another_folder) {
    return 301 $scheme://AnotherDomain.com;
}

# Some_Name
location ~*/(some_name) {
    return 301 $scheme://some_name.example.com;
}

NOTE: Answer typed on my phone while holding a sleeping baby, so assume syntax errors.

  • This is exactly what I did earlier today (see my comment to my own post last night). It works great, A couple additional potential benefit compared to my original attempt too: 1) by disabling just the one config file (i.e. taking it out of sites enabled), the redirects that were based on subfolders get disabled too (a desired effect in this situation), 2) the first server block changing www. subdomain to no subdomain is applied to all subsequent location blocks which reduced my initially kludgy code by about half. I can still separately maintain server directives for subdomains too! – FBachofner Oct 20 '17 at 8:00
  • Hi Moshe: to your knowledge is there a best practice for the location of thusly included files? Good luck with your sleeping baby. Mine are now 8 and 6. As great as everything is today, I miss those early baby days! :-) – FBachofner Oct 20 '17 at 18:39
  • @FBachofner Not that I know of, though there are some conventions that I have seen. One important thing to keep in mind is that relative paths are all resolved from the location of the main Nginx config file, not from the location of the file that is doing the including. Often, people will create a snippets directory inside the Nginx config directory and put all of their included files in there. – Moshe Katz Oct 20 '17 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.