Nginx config for Restful API behind proxy

nginxreverse-proxy

I am trying to move my node proxy from port 8080 to 80 and hitting walls.
I want my RESTful API to be behind a nginx reverse-proxy listening on port 80 on location /api/path instead.

(Port 8080 wasn't accessible for some enterprise users behind overzealous firewalls.)

I used to direct requests to https://domain.tld:8080/ to http://localhost:1337. No problems via:

server {
    listen      8080;
    server_name  domain.tld;

    ssl on; #some other SSL config removed for clarity

    location / {
        proxy_redirect          off;
        proxy_pass_header       Server;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Scheme $scheme;
        proxy_set_header        Host $http_host;
        proxy_set_header        X-NginX-Proxy true;
        proxy_connect_timeout   5;
        proxy_read_timeout      240;
        proxy_intercept_errors  on;

        proxy_pass              http://127.0.0.1:1337;
    }
}

Now I am trying to move it to location api/path/ and away from port 8080 via:

server {
    listen       443 ssl http2;
    listen       [::]:443 ssl http2;
    server_name  domain.tld;
    root         /path/to/html/;

    ssl on; #some other SSL config removed for clarity

    location /api/path/ {
        proxy_redirect          off;
        proxy_pass_header       Server;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Scheme $scheme;
        proxy_set_header        Host $http_host;
        proxy_set_header        X-NginX-Proxy true;
        proxy_connect_timeout   5;
        proxy_read_timeout      240;
        proxy_intercept_errors  on;

        proxy_pass              http://127.0.0.1:1337;
    }
}

This results in:

$ curl -i -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d '{}' https://domain.tld/api/path

TTP/1.1 404 Not Found
Date: Thu, 08 Sep 2016 01:29:35 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 25
Connection: keep-alive
X-Powered-By: Express
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains;

Cannot POST /api/path

Now I read that you can't POST to static pages which means you do something like:

error_page  405          @405;

location = @405 {
    root         /path/to/html/;
}

But as I can't find enough infos about this it's not working. GET works as normal but POST will error out with Cannot POST api/path. What can I do here?

Appreciate any help.

Update

I needed to enable the proxy_redirect as @techraf pointed out so my successful config looks like this now. Hope it helps someone.

server {
    listen       443 ssl http2;
    listen       [::]:443 ssl http2;
    server_name  domain.tld;
    root         /path/to/html/;

    ssl on; #some other SSL config removed for clarity

    location /api/path/ {
        proxy_redirect          http://localhost:1337/  /api/path/; #<-- change
        proxy_pass_header       Server;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        X-Scheme $scheme;
        proxy_set_header        Host $http_host;
        proxy_set_header        X-NginX-Proxy true;
        proxy_connect_timeout   5;
        proxy_read_timeout      240;
        proxy_intercept_errors  on;

        proxy_pass              http://127.0.0.1:1337;
    }
}

Best Answer

If you want to point /api/path/ to the root of your redirect destination, you need to use:

proxy_redirect http://localhost:1337 https://domain.tld/api/path/