switch off html wrapping of errors in nginx - nginx

I use nginx on Ubuntu to forward requests to a Spring Boot-driven API server. Sometimes the API returns a body with 4xx and 5xx errors, that the client application consumes. E.g. in the API code I might return:
{
"message": "blah"
}
However nginx seems to wrap errors up into some HTML and embeds the response within them. Is there any way to disable this behavior? And is there a way to do it en masse (i.e. for all 4xx and 5xx errors, without explicitly writing them all out with error_page for example)
Similar question and accepted answer here, however that seems to be a bit of hack. I'm sure there's a better way of doing this...
EDIT: Config looks like this:
server {
listen 80;
server_name my.domain.com;
location / {
proxy_pass http://127.0.0.1:9001;
}
}

You just need to add a error_page directive inside the location
server {
listen 80;
server_name my.domain.com;
location / {
error_page 404 = 404;
proxy_pass http://127.0.0.1:9001;
}
}
What this would do is cancel error_page from previous directives set at the http block. And pass the result back to the client as it is. You don't want the codes for which JSON should be sent back to the client in this error_page directive.

You can try update your nginx conf and add:
error_page 403 /error403.html;
location = /error403.html {
root html;
}
or for group of erros:
error_page 500 502 504 /50x.html;
location = /50x.html {
root html;
}
And here you can replace html files to json so nginx will return json respnse, like:
error_page 404 /404.json;
location = /404.json {
root html;
}
and don't forget put 404.json (and all appropriate files) into root which is specified in config.
In your config it will look like:
server {
listen 80;
server_name my.domain.com;
location / {
proxy_pass http://127.0.0.1:9001;
}
error_page 404 /404.json;
location = /404.json {
root html;
}
error_page 500 502 504 /50x.json;
location = /50x.json {
root html;
}
}

Related

Changing status code from 502 to 503 in fallback route

I'm using nginx as proxy server for my project. In case my app is offline for maintenance I'd like to show a fallback page. This works fine so far. The only problem is, that the server response with a 502 error code - which makes sense. How do I change it to a 503 route in my fallback though?
server {
listen 80;
error_page 500 502 503 504 #fallback;
location / {
proxy_pass http://0.0.0.0:3000;
}
location #fallback {
// I need this to answer with a status of 503 instead of a 502
root /srv/my-project/static;
try_files /fallback.html;
}
}
you can set a error page nginx error page
and set somethig like
error_page 502 =503 /maintenance.html
or something like
location / {
error_page 502 =503 /maintenance.html;
include proxy_params;
proxy_pass http://unix:/var/run/my.sock;
}
location /maintenance.html {
return 503;
}
source : How can I make Nginx return HTTP 503 when my proxied app server is down?
Thanks #shalbafzadeh for that answer, that solved it for me.
In my very particular situation the solution looks like this:
server {
listen 80;
error_page 502 =503 #fallback; <-- THIS
location / {
proxy_pass http://0.0.0.0:3000;
}
location #fallback {
root /srv/my-project/static;
try_files /fallback.html;
}
}

How to Proxy Pass from / to /index.html

I'm currently working on a JS Project, that uses the url path. Now if I go on my website with example.com/, the JavaScript won't work, because I actually need example.com/index.html.
I'm already using an reverse proxy to proxy pass to two different docker containers. So my idea was to pass the request to example.com/index.html when example.com/ is called. But I can't figure out the regex stuff to achieve this goal.
My old config:
server {
listen 80;
server_name example.com;
# allow large uploads of files - refer to nginx documentation
client_max_body_size 1G;
# optimize downloading files larger than 1G - refer to nginx doc
before adjusting
#proxy_max_temp_file_size 2G;
location / {
proxy_pass http://structure.example:80;
}
location /cdn {
proxy_pass http://content.example:80;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Stuff I tried:
server {
listen 80;
server_name example.com;
# allow large uploads of files - refer to nginx documentation
client_max_body_size 1G;
# optimize downloading files larger than 1G - refer to nginx doc
before adjusting
#proxy_max_temp_file_size 2G;
location / {
proxy_pass http://structure.nocms:80/index.html;
}
location ~* \S+ {
proxy_pass http://structure.nocms:80;
}
location /cdn {
proxy_pass http://content.nocms:80;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
The accepted answer has one disadvantage: going to example.com explicitly redirects to example.com/index.html (that is, returns 301 Moved permanently), which is not always desired.
Instead, I suggest to prepend location / with another directive, location = /, which is designed to the root URL only:
location = / {
proxy_pass http://structure.nocms:80/index.html;
}
location / {
proxy_pass http://structure.nocms:80;
}
The above instructs nginx to pass requests to example.com directly to http://structure.nocms:80/index.html, while requesting any other URLs in example.com/* would pass the request to the corresponding URL in the downstream.
Below config should work for you
server {
listen 80;
server_name example.com;
# allow large uploads of files - refer to nginx documentation
client_max_body_size 1G;
# optimize downloading files larger than 1G - refer to nginx doc
before adjusting
#proxy_max_temp_file_size 2G;
location = / {
rewrite ^ /index.html permanent;
}
location / {
proxy_pass http://structure.example:80;
}
location /cdn {
proxy_pass http://content.example:80;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

NgINX error_page

I have some virtual host configurated on my server.
I Need to set a common error_page for all them.
host1.conf
server {
listen 80;
server_name host1.com
root host1/path;
location / {
proxy_pass http://localhost:xxxx;
}
}
host2.conf
server {
listen 80;
server_name host2.com
root host2/path;
location / {
proxy_pass http://localhost:xxxx;
}
}
and so on.
1) Could I set the error_page in every .conf file?
Could I set the error_page in every .conf file? Or I'm able to set it only in a default .conf?
2) Problem with error redirect
I have a 404.html page and 50x.html page too on my default server.
So I added the follow instructions to all my host .conf files
error_page 404 /404.html;
location = /404.html {
root /path/to/default;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /path/to/default;
}
I see rightly that page but... they have some css, webfonts and images inclusion. That inclusions are not resolved, it seems they are looked on host root instead of default root.
There is a solution for have a single error page setted on a default site configuration and reused in all others conf?

Nginx error pages not working

I have the following vhost entry
server {
listen 80;
server_name example.com www.example.com;
#access_log /var/log/nginx/nginx-access.log;
location /media/ {
root /home/luke/django/solentcms;
}
location /admin/media/ {
root /home/luke/virts/django1.25/lib/python2.7/site-packages/django/contrib/admin/media;
}
location / {
proxy_pass http://127.0.0.1:8001;
}
error_page 404 /404.html;
location = /404.html {
root /home/luke/django/solentcms/404;
allow all;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /home/luke/django/solentcms/404;
allow all;
}
}
However, 404's and 50x errors are still be re-directed to the horrible nginx default pages.Any ideas as to why? This syntax works on one of my other servers.
Cheers.
Are the errors coming from your backend? You may need to add proxy_intercept_errors on; alongside your proxy_pass.

nginx: how to always return a custom 404 page for the default host

I have nginx 0.8.53 configured with some virtual hosts which work as desired. However, due to nginx's "best match" on virtual hosts, I need to add a default host to catch all requests that aren't for a specific virtual host. I would like the default host to return a custom 404 page that I created instead of the default nginx 404 page.
I assumed I needed something like:
# The default server:
server {
listen 80 default_server;
server_name everythingelse;
# Everything is a 404
location / {
return 404;
}
error_page 404 /opt/local/html/404.html;
}
But this still returns the default nginx 404 page. It seems the return 404 ignores the error_page config.
Here what I have in my conf to make it work:
# The default server.
server {
listen 80 default_server;
server_name everythingelse;
error_page 404 /404.html;
# Everything is a 404
location / {
return 404; #return the code 404
}
# link the code to the file
location = /404.html {
#EDIT this line to make it match the folder where there is your errors page
#Dont forget to create 404.html in this folder
root /var/www/nginx/errors/;
}
}
Very few directives in nginx take a filesystem path. You want something like:
# The default server.
server {
listen 80 default_server;
server_name everythingelse;
root /opt/local/html;
error_page 404 /404.html;
# Everything is a 404
location / {
return 404;
}
# EDIT: You may need this to prevent return 404; recursion
location = /404.html {
internal;
}
}
Move the error_page directive up the conf to before you call return 404.
This should work:
# The default server.
#
server {
listen 80 default_server;
server_name everythingelse;
error_page 404 /error_docs/404.html;
# Everything is a 404
location / {
return 404;
}
# Custom Error Page
location /error_docs {
alias /opt/local/html/;
log_not_found off;
access_log off;
}
}
This will use the same custom one for all sites (servers). You need to add the error docs location.
http {
error_page 404 /error_docs/404.html;
...
# The default server.
#
server {
listen 80 default_server;
server_name everythingelse;
# Everything is a 404
location / {
return 404;
}
# Custom Error Page
location /error_docs {
alias /opt/local/html/;
log_not_found off;
access_log off;
}
}
}
Before the server block, you are probably using the include instruction :
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
...
}
I had the same issue, and fixed it by removing the include line:
server {
listen 80;
...
}
In NGINX v1.14 (released in 2019-12-26) you cannot use location = /404.html. Removing the = (equals sign) works:
server {
listen 80;
server_name everythingelse;
error_page 404 /404.html;
location / {
return 404;
}
location /404.html {
root /opt/local/html;
}
}
Since both root and error_page are valid directives at http block scope, one can leverage the inheritance behavior of nginx configuration.
To share custom error pages between all my vhosts (so that requests on unknown vhosts or inexistent resources in known vhosts get my custom error pages as a response according to error_page definition), I use the following recipe.
1. Add those three lines to /etc/nginx/nginx.conf
# …
root /var/www/whatever # Used by undefined hosts
error_page 403 404 =404 /404.html
error_page 502 503 504 =500 /500.html
# …
2. Create /etc/nginx/sites-available/catchall with the following snippet as a «catch all» default virtual server.
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL rules here if required
server_name _;
}
3. Create 404.html and 500.html files in each document root where a custom error has to be used (or link the ones in /var/www/whatever), otherwise defaults will be used instead.
That said, not all directives can inherit from a higher level scope, and even worse, some inheritance is unintuitive and doesn't behave as you might expect.
Understanding the NGINX Configuration file structure and configuration context
Interesting SO thread: Location nesting
(Using Debian9 and nginx/1.10.3)

Resources