3

I have an angular app, my-app, which I build locally with ng build --prod and serve with Nginx dockerized, the Dockerfile is:

FROM nginx:alpine
COPY /dist/my-app /usr/share/nginx/html
EXPOSE 80

As long as I launch a container based on an image build with this Dockerfile, it works. Though, I need to put another Nginx acting as a reverse proxy before this one, I want to redirect the traffic with a route like /my-app to the internal Nginx serving Angular, like so:

http://DOMAIN/my-app ---> Reverse Proxy ---> Nginx+Angular

I'll use Docker Compose for local dev. My docker-compose.yml is very simple:

version: '3'

services:
    nginx:
        container_name: my-nginx
        build: ./nginx
        ports:
            - "80:80"
    my-app:
        container_name: my-app
        build: ./my-app

For the Angular app, I redefine "baseHref": "./my-app/" in my angular.json file, I build again and I configure the reverse proxy as follows:

events {}

http {

  server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root                /var/www;
    index               index.html;

    location / {
        index           index.html;
    }

    location /my-app {
      rewrite                     /my-app/(.*) /$1 break;
      proxy_pass                  http://my-app:80;
      proxy_set_header Host       $host;
      proxy_set_header Upgrade    $http_upgrade;
      proxy_set_header Connection $http_connection;
      proxy_set_header Host       $host;
    }
  }
}

Here, the index.html in the location / directive is a custom one, not the Angular app's one. Thus, I expect my reverse proxy to serve the index.html when visiting the route /, which it does, but I get a 400 Bad Request error when I try to visit /my-app/. Does someone have a solution for this? What am I getting wrong? Thanks!

1 Answer 1

4

Just guessing. I would do it that way.

    # Maybe not necessary to redirect from /my-app to /my-app/.
    location ~ ^/my-app$ {
      set $myargs $args;  # workaround to encode spaces in query string!
      return 303 $scheme://$server_name/my-app/$is_args$myargs;
    }

    location /my-app/ {  # works mostly with and sometimes without slash at end!
      proxy_pass                  http://my-app:80/;  # slash at end is goddamn important here; it hides /my-app/ and does all the $request_uri or regex, $is_args and $args magic for you!
      proxy_set_header Host       $host;
      proxy_set_header Upgrade    $http_upgrade;
      proxy_set_header Connection $http_connection;
      proxy_set_header Host       $host;
    }

If your back end sends redirects you are maybe screwed. Check with curl -IL http://my-app. If you see 301, 302, 303 up to 308 with a target Location: - it's a redirect. But maybe my other answer there can help (rewrite redirects): https://serverfault.com/a/986034/304842 or try proxy_redirect. The problem that I seeing is that you want websockets!? Maybe you need sub_filter or subs_filter too, to remove /my-app/ from source code for other links and resources. Check with [F12] -> Network in your browser.

Sign up to request clarification or add additional context in comments.

4 Comments

If I send curl -IL http://localhost:8081, I get: $ curl -IL http://localhost:8081 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 808 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0HTTP/1.1 200 OK ...
Still not working, now the URL localhost/my-app returns "400 Bad Request nginx/1.19.2".
Dunno, can you update question with your current config? Also /var/log/nginx/error.log could be interesting.
goddamn slash in proxy_pass take me 15 hours, until I read this answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.