Nginx includes config files not in order?

Is the order in which Nginx includes configuration files fixed, or random? Apache explicitly states wildcard characters are expanded in alphabetical order. With Nginx it seems this does not apply, and the manual says nothing about it.

In my setup, 20_example.com was included before 00_default, which defeats my purpose of defining shared directives (like log formats) there.


Solution 1:

According to nginx source code it uses glob() function with GLOB_NOSORT parameter, so, the order of file inclusion could not be clearly established.

This was changed in November 2012, first released in 1.3.10. From the changefile:

now if the "include" directive with mask is used on Unix systems, included files are sorted in alphabetical order.

Solution 2:

AD7six's answer is not wholly correct. Order also matters when two server blocks have the same "specificity", for example when both use regexes in server_name, and the incoming request matches both:

server {
    server_name ~^(www\.)?(?<domain>foo\.com|bar\.com|baz\.com)$;
    ...
}

and

server {
    server_name ~^(www\.)?(?<domain>.+)$;
    ...
}

In this scenario, the two server blocks cannot be spread over two files because their order could not then be guaranteed.

Solution 3:

As OP points out log_format order it's indeed very important, in the case of custom log_formats, if you place in the same dir both types files, some files with log_formats, some files with servers blocks that make use of those log_formats, result will be a highly unrepeatable configuration.

At work when we first moved our hand made nginx farm into puppet, we started to see some nginx installations from scratch to fail in an identical hardware/setup, after a lot of debugging bizarre situations like having two /etc/nginx/* (-r) with an md5match and same binary producing different results (invalid log_format error on one and working on other), we learned the hard way that order it's indeed very important for some directives like log_format.

We fixed the issue by just moving server blocks generation out of conf.d/* into another folder included after conf.d/*.