16

In the lines below, I might have a site-specific configuration file that contains additional fastcgi_params unique to that site. If this file exists I want to load it.

server {
        listen 80 default;
        server_name _;
        root /path/www/$host;

        # Pass PHP scripts to php-fastcgi listening on port 9000
        location ~ \.php {
                include fastcgi_params;
                fastcgi_pass 127.0.0.1:9000;


                if (-f /path/www/$host/nginx.conf) {
                        include /path/www/$host/nginx.conf;
                }
        }
}

However, this doesn't work and the error I get is:

nginx: [emerg] "include" directive is not allowed here in ...

Update

I thought that rather than checking separatly, I could let include check for me.

server {
        listen 80 default;
        server_name _;
        root /path/www/$host;

        # Pass PHP scripts to php-fastcgi listening on port 9000
        location ~ \.php {
                include fastcgi_params;
                fastcgi_pass 127.0.0.1:9000;

                include /path/www/$host/*.nginx;
        }
}

However, this doesn't seem to be working.

Xeoncross
  • 4,269
  • 12
  • 42
  • 55

4 Answers4

38

Well, this is rather old, but anyway, I found a work-around.

I have a setup with vhosts configured in this style:

/etc/nginx/sites-enabled/site.com.conf

Instead of checking if the file exists (which isn't possible), I simply do:

include /etc/nginx/sites-customizations/site.com.*.conf

This way I can simply create a file in the sites-customizations-folder, which by my convention, is named the same as the main configuration. The * works pretty much like the if, as it doesn't break if there is no extra configuration files. If you like, this also enables you to add multiple extra configurations in separate files.

user158786
  • 381
  • 3
  • 2
10

include does its thing during server start - runtime variables like $host can't be used, nor is it able to be used in an if context, as you found out.

You'd need to split up the server blocks for different hosts. Sorry!

Shane Madden
  • 112,982
  • 12
  • 174
  • 248
8

I take advantage of the glob() function pattern expansion, which is used by nginx in the include directive, and works well on my Debian servers.

In your case, try to replace this line:

include /path/www/$host/nginx.conf;

with this one:

include /path/www/<hostname>/nginx[.]conf;

it's a file mask that matches only one file, and won't make nginx complain if the file does not exist. However variables are not allowed in include directives, so you must supply a fixed value in <hostname>. We had to create a script that generates individual .conf files (one per vhost).

Edit

As Gerald Schneider pointed out, I was suggesting to keep $host in the replacement, which is not allowed. I've changed the suggestion above.

  • 1
    the variable `$host` is still not going to work here. – Gerald Schneider Jan 04 '18 at 14:58
  • 1
    Sorry, you are right, variables are not allowed in include directives. We use a python script that creates a single .conf for each vhost out of a list, but we make extensive use of "custom" additional per-vhost deviations from standard. – Alberto Pastore Jan 04 '18 at 17:53
  • could you kindly share your python code with me? – mahyard Apr 30 '20 at 10:50
  • 1
    the include with `nginx[.]conf` is not working, it does not include the file. Bit without the braclets it works only as long as the file exists. (Tested with version 1.18.0) But `nginx*.conf` works fine (if file exists) and doesnt complain if it not exists. – Radon8472 Oct 02 '20 at 14:53
  • 1
    @Radon8472 we are currently and effectively using the square bracket syntax in our production web farm on version 1.18.0, I don't know why that's not working for you, see this config snippet: `server { set $vhost theo-s.it; server_name theo-s.it www.theo-s.it; include listen/fpm.conf; include listen/fpm-ssl.conf; include web/sites-ssl/theo-s.it[.]conf; include web/macros/gestion.conf; include web/sites-customs/theo-s.it[.]conf; }` – Alberto Pastore Oct 03 '20 at 11:19
  • @Alberto Pastore Maybe it is only an issue in the windows version of nginx. – Radon8472 Oct 04 '20 at 12:33
  • I have to say, this is pretty much what I needed. It seems to be a bit stupid, we should have nginx configurations such as `require` and `include`, like we've got under PHP... and possibly other languages. Nevertheless, this workaround is quite useful under Debian/Linux when using WordPress, since `nginx[.]conf` is really needed by _some_ plugins (such as, say, [W3TC](https://wordpress.org/plugins/w3-total-cache/)) – Gwyneth Llewelyn Feb 06 '21 at 18:39
6

I know this is old but solution might help someone looking for an answer like I did.

I had a bunch of redirects that I needed to include for a specific host only and while include is not allowed in the if directive, I ended up adding the if inside the file I was including...

So I have an include /etc/nginx/conf.d/redirects and inside that file I have:

if ($host = "www.example.com") {
    # Some conf or redirects for this site only.
}
Titi
  • 220
  • 2
  • 6