Default error_page for multiple vhosts

I’m trying to set a default error_page for my entire nginx server (as
in for all vhosts)

I’m using following settings:

http {
error_page 404 /var/www/default/404.html;

server {
    root /var/www/mydomain.com/;
}

}

But I’m getting this error:
[error] 16842#0: *1 open()
“/var/www/mydomain.com/var/www/default/404.html” failed (2: No such
file or directory)

While I do understand the error, and I do understand why it’s
happening, I can’t understand why can’t I tell NGINX to
user the default error_page as an absolute path instead of appending
it to the root of my vhost.

What I’m trying to achieve is being able to user
/var/www/default/404.html error_page from all my vhosts without
having to add it to all server{}. I think adding it for my 300 domains
is an overkill.

I asked in serverfault and I did got a semi-solution using includes,
but this solution still requires me to edit every
single server{}, which I really don’t want to.

Is there any other way I could achieve what I’m trying?

Original serverfault question:

Regards!


alexandernst

On Fri, Feb 22, 2013 at 09:32:33AM +0100, Alexander Nestorov wrote:

Hi there,

I’m trying to set a default error_page for my entire nginx server (as
in for all vhosts)

Based on the way that nginx configuration inheritance works, that is
unlikely to be usefully possible at http{} level when you also want to
add an extra “error_page 502” to a few domains.

(That’s not “it can’t work”; it’s “even when you add it at http{}
level, be aware that some later configuration changes may undo it in
some cases”.)

While I do understand the error, and I do understand why it’s
happening, I can’t understand why can’t I tell NGINX to
user the default error_page as an absolute path instead of appending
it to the root of my vhost.

What’s not to understand? error_page takes a uri, not a filename.

I guess that, up to now, no-one who wanted error_page to be able to
take a filename provided a patch with a convincing explanation of why
it would be useful to include.

What I’m trying to achieve is being able to user
/var/www/default/404.html error_page from all my vhosts without
having to add it to all server{}. I think adding it for my 300 domains
is an overkill.

I think that if you have 300 domains, then you should already have a way
to auto-generate the configuration. Just put the suggested configuration
into the template and regenerate.

(And if you don’t have such a way, then you can probably do a one-off
thing with some text processing language; and you should probably
consider creating such a way, in order to make future “global” changes
easier for you.)

I asked in serverfault and I did got a semi-solution using includes,
but this solution still requires me to edit every
single server{}, which I really don’t want to.

Find each line “server {”. Add one line with “include”, or add a few
lines with the “error_page” and “location = /404 {}” configuration. Not
a lot of sed.

Run “nginx -t” to check for syntax errors.

If you’re going to use nginx, it is likely to be more comfortable for
you if you adapt to its configuration method.

What you see as “overkill” and “semi-solution” and “don’t want to”,
I see as elegant and simple-to-read.

Is there any other way I could achieve what I’m trying?

error_page which takes a filename – not without patching.

Given that you want a common error_page which uses the same uri in each
server (which is ok), but you don’t want to use per-server configuration
to map that uri to a common filename – not that I can see.

f

Francis D. [email protected]

On Fri, 22 Feb 2013 09:32:33 +0100, Alexander Nestorov
[email protected] wrote:

I’m trying to set a default error_page for my entire nginx server (as
http {
error_page 404 /var/www/default/404.html;
server {
root /var/www/mydomain.com/;
}
}
Is there any other way I could achieve what I’m trying?

What about soft linking it into wherever you want it?

in the OS

ln -s /var/www/default/404.html /var/www/mydomain.com/

#in Nginx config
error_page 404 /404.html;

Regards,

M.

Thank you both for the replies :slight_smile:

I already thought about soft links and some hack with grep+sed, but
that’s not I really wanted to ask.

What I really ment to ask/say is: it will be really usefull to set
some default rules that could be overriden later
on each server{}.

Example:

It would be really usefull (in my particular case) to set error_page
to some absolute path so that all server{}
get error_page automatically. Then, if my domain 42 needs a custom
error_page I could just add the error_page
to that server{} and it will get overriden.

This is (the way I see it) more elegant than re-generating server{}
templates or doing ln -s.
Think about http{} as a class and server{} as a derived class in any
OOP language.


alexandernst

On 2/22/13 12:42 PM, Alexander Nestorov wrote:

Example:

It would be really usefull (in my particular case) to set error_page
to some absolute path so that all server{}
get error_page automatically. Then, if my domain 42 needs a custom
error_page I could just add the error_page
to that server{} and it will get overriden.

Alexander,

I think I achieved what you’re after:

  • default 403, 404 and 503 error pages in /usr/local/share/www/
  • custom 404, 404 and 504 error pages for each vhost in
    $document_root/

Typically, a vhost in /etc/nginx/sites-available/some.domain.org
includes vhost.conf which includes errors.conf
Tell me if that helps.

Feedback from others appreciated!
Gregory

error.conf:
error_page 403 @403;
error_page 404 @404;
error_page 503 @503;

location @403 {
try_files /403.html @403_fallback;
}

location = /403.html {
if (-f $document_root/offline) {
error_page 503 @offline;
return 503;
}
return 404;
}

location @403_fallback {
root /usr/local/share/www;
try_files /403.html =403;
}

location @404 {
try_files /404.html @404_fallback;
}

location = /404.html {
if (-f $document_root/offline) {
error_page 503 @offline;
return 503;
}
return 404;
}

location @404_fallback {
root /usr/local/share/www;
try_files /404.html =404;
}

location @503 {
try_files /503.html @503_fallback;
}

location = /503.html {
if (-f $document_root/offline) {
error_page 503 @offline;
return 503;
}
return 404;
}

location @503_fallback {
root /usr/local/share/www;
try_files /50x.html =503;
}


offline.conf

location @offline {
try_files /offline.html @503;
}

location = /offline {
if (-f $document_root/offline) {
error_page 503 @offline;
return 503;
}
return 404;
}

location = /offline.html {
if (-f $document_root/offline) {
error_page 503 @offline;
return 503;
}
return 404;
}


vhost.conf

include errors.conf;
include offline.conf;

location / {
if (-f $document_root/offline) {
error_page 503 @offline;
return 503;
}
try_files $uri $uri/ /index.php;
}


IRCNet /msg guardian | [email protected] | Twitter @planetdnews

On Fri, Feb 22, 2013 at 12:42:17PM +0100, Alexander Nestorov wrote:

Hi there,

What I really ment to ask/say is: it will be really usefull to set
some default rules that could be overriden later
on each server{}.

That is already the case, within the limits of the nginx configuration
inheritance model (which is approximately: inheritance is by
replacement,
or not at all) and valid directive contexts.

Example:

It would be really usefull (in my particular case) to set error_page
to some absolute path so that all server{}
get error_page automatically. Then, if my domain 42 needs a custom
error_page I could just add the error_page
to that server{} and it will get overriden.

From the nginx configuration inheritance point of view, that already
happens.

Except that error_page take a uri, not a filename.

This is (the way I see it) more elegant than re-generating server{}
templates or doing ln -s.
Think about http{} as a class and server{} as a derived class in any
OOP language.

Yes, that is how it works already.

What you want is an alternative directive which is like error_page but
takes a filename.

Nothing to do with changing the inheritance model. And therefore
conceptually much simpler to get into the code base, if someone cares
enough to write it.

f

Francis D. [email protected]

Thank you for the example config Gregory! :slight_smile:

I’ll try it (not sure if I’ll be able to do it until monday) and I’ll
say if everything works as expected.

Regards :slight_smile:


alexandernst

Gregory, hi, I tested your config and it’s working, but that’s even more
complex
than just writing the error_page in each server{}. Thank you for you
help
anyways :slight_smile:

Francis, I filled a feature request (#307), let’s see what happens

Regards!