Issue
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!
Solution
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.