Difference between revisions of "Nginx"

From Leaky
Jump to: navigation, search
(Using nginx as a proxy during server migrations)
 
m (Custom error pages)
 
(3 intermediate revisions by the same user not shown)
Line 21: Line 21:
 
     }
 
     }
 
  }
 
  }
 +
 +
If using nginx to proxy to an application such as [http://gitea.io/ gitea], when pushing a large repository you may get an HTTP 413 error.
 +
 +
Delta compression using up to 4 threads.
 +
Compressing objects: 100% (2688/2688), done.
 +
error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large
 +
fatal: The remote end hung up unexpectedly
 +
Writing objects: 100% (2756/2756), 845.89 MiB | 26.77 MiB/s, done.
 +
Total 2756 (delta 674), reused 0 (delta 0)
 +
fatal: The remote end hung up unexpectedly
 +
 +
The reason is that nginx buffers proxied requests by default and git is trying to push the whole thing in a single request. The quick solution is to increase ''client_max_body_size'' to something large enough - for example, 2GB.
 +
 +
server {
 +
    ...
 +
    client_max_body_size 2000m;
 +
}
 +
 +
In addition to this, you may wish to disable request buffering:
 +
 +
server {
 +
    ...
 +
    location / {
 +
        ...
 +
        proxy_http_version 1.1;
 +
        proxy_request_buffering off;
 +
    }
 +
}
 +
 +
== Custom error pages ==
 +
 +
Proxying to a backend server (such as Catalyst+starman) but returning any files which actually exist in /var/www/html such as CSS or JavaScript files.
 +
 +
        root /var/www/html;
 +
 +
        location / {
 +
                try_files $uri @starman;
 +
        }
 +
 +
        location @starman {
 +
                proxy_set_header X-Real-IP $remote_addr;
 +
                proxy_set_header X-Forwarded-For $remote_addr;
 +
                proxy_set_header SSL on;
 +
                proxy_set_header X-Forwarded-Proto https;
 +
                proxy_set_header Host $host;
 +
                proxy_pass http://127.0.0.1:3003;
 +
        }
 +
 +
If there's an error (for example the backend server is down) you'll get a "502 Bad Gateway" response from nginx. To output a static HTML page, you can use the error_page directive
 +
 +
error_page 502 /error.html
 +
 +
This works fine except that the response code 502 is replaced with a 200 and this will cause your error page to be cached by Google etc. Instead of the above, add a section as follows.
 +
 +
        error_page 503 =503 @proxyisdown;
 +
        error_page 502 =502 @proxyisdown;
 +
 +
        location @proxyisdown {
 +
                rewrite ^.*$ /error.html break;
 +
                add_header Retry-After 600;
 +
                expires 1s;
 +
        }
 +
 +
This causes the status code to be returned still, but outputs the content from the page error.html (located in the root). The rewrite to ignore any path is required otherwise a valid url handled by the backend (e.g. /login) will return a "404 Not found" if the backend is down. This is because it attempts to return the content of /var/www/html/login which doesn't exist.

Latest revision as of 12:25, 13 November 2018

To use nginx as a proxy - for example from an old server to a new one during a migration, you need to set the Host header to be $host

There are also some other headers that could be useful so just set the whole lot in the global part of /etc/nginx/conf.d/default.conf

proxy_set_header    Host                $host;
proxy_set_header    Connection          "";
proxy_set_header    X-Real-IP           $remote_addr;
proxy_set_header    X-Forwarded-Port    $server_port;

Setup the server to listen either on every interface port 80, or a specific IP on port 80 using the listen directive.

server {
   listen      80 default_server;
   listen      [2a02:af8:3:2000::7982]:80 default_server;
   server_name _;

And make sure that the entire site from / downwards is proxied through to the new IP address

   location / {
       proxy_pass http://213.229.84.27;
   }
}

If using nginx to proxy to an application such as gitea, when pushing a large repository you may get an HTTP 413 error.

Delta compression using up to 4 threads.
Compressing objects: 100% (2688/2688), done.
error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large
fatal: The remote end hung up unexpectedly
Writing objects: 100% (2756/2756), 845.89 MiB | 26.77 MiB/s, done.
Total 2756 (delta 674), reused 0 (delta 0)
fatal: The remote end hung up unexpectedly

The reason is that nginx buffers proxied requests by default and git is trying to push the whole thing in a single request. The quick solution is to increase client_max_body_size to something large enough - for example, 2GB.

server {
    ...
    client_max_body_size 2000m;
}

In addition to this, you may wish to disable request buffering:

server {
    ...
    location / {
        ...
        proxy_http_version 1.1;
        proxy_request_buffering off;
    }
}

Custom error pages

Proxying to a backend server (such as Catalyst+starman) but returning any files which actually exist in /var/www/html such as CSS or JavaScript files.

       root /var/www/html;

       location / {
               try_files $uri @starman;
       }

       location @starman {
               proxy_set_header X-Real-IP $remote_addr;
               proxy_set_header X-Forwarded-For $remote_addr;
               proxy_set_header SSL on;
               proxy_set_header X-Forwarded-Proto https;
               proxy_set_header Host $host;
               proxy_pass http://127.0.0.1:3003;
       }

If there's an error (for example the backend server is down) you'll get a "502 Bad Gateway" response from nginx. To output a static HTML page, you can use the error_page directive

error_page 502 /error.html

This works fine except that the response code 502 is replaced with a 200 and this will cause your error page to be cached by Google etc. Instead of the above, add a section as follows.

       error_page 503 =503 @proxyisdown;
       error_page 502 =502 @proxyisdown;

       location @proxyisdown {
               rewrite ^.*$ /error.html break;
               add_header Retry-After 600;
               expires 1s;
       }

This causes the status code to be returned still, but outputs the content from the page error.html (located in the root). The rewrite to ignore any path is required otherwise a valid url handled by the backend (e.g. /login) will return a "404 Not found" if the backend is down. This is because it attempts to return the content of /var/www/html/login which doesn't exist.