Nginx rewrite on docker machine when host port != container port

Solution 1:

The HTTP clients will put the port in the Host header. If you use the original value of the host header when doing the redirect, it should work as expected. I tested the following code and looks to be doing exactly what you requested:

location ~ ^.*[^/]$ {
    try_files $uri @rewrite;
}
location @rewrite {
    return 302 $scheme://$http_host$uri/;
}

> GET /bla HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Server: nginx/1.9.7
< Date: Sun, 29 Nov 2015 06:23:35 GMT
< Content-Type: text/html
< Content-Length: 160
< Connection: keep-alive
< Location: http://localhost:8080/bla/

Solution 2:

The simplest solution is to remove the index directive and not rely on explicit or implicit $uri/ redirects. For example:

server {
  listen 80;
  root /var/www;
  location /docs {
    try_files $uri $uri/index.html =404;
  }
}

This isn't identical behaviour as it avoids the redirect altogether. If you wanted a trailing slash redirect like the index module gives, then a more complex solution is required. For example:

server {
  listen 80;
  root /var/www;
  location /docs {
    try_files $uri @redirect;
  }
  location @redirect {
    if ($uri ~* ^(.+)/$) { rewrite ^ $uri/index.html last; }
    if (-d $document_root$uri) { return $scheme://$host:8080$uri/; }
    return 404;
  }
}

Tags:

Docker

Nginx