Angular App running on nginx and behind an additional nginx reverse proxy
Solution 1
Firstly I prefer the approach one service, one container providing redirection with nginx. It also covers almost automatically https using a dockerized nginx reverse proxy with certificates. You can also use letsencrypt certificates if you want. You can deploy your Angular applications into containers behind the reverse proxy.
Below I describe the steps for your docker deployment. I also include portainer which is a GUI for your container deployment:
- Run the nginx in the port 443 sharing the certificates generated for your.domain using the option -v $HOME/certs:/etc/nginx/certs. Put the certificates somewhere on the host for instance /etc/nginx/certs. Option --restart=always is needed to automatically run the container when the server reboot:
docker run -d --name nginx-proxy --restart=always -p 443:443 -v /root/certs:/etc/nginx/certs -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
- Your app 1 and 2 should be deployed in appX.yourdomain and must be redirected to the docker IP (this way nginx can redirect the subdomain to your container).
- Dockerfile MUST expose the web service in different ports (8080 and 8081). The component should be also deployed on that port
- The most important thing is that application 1 and 2 containers must include the option -e VIRTUAL_HOST=appX.yourdomain and PROXY_ADDRESS_FORWARDING=true:
docker run --name app1 --restart=always -d -e PROXY_ADDRESS_FORWARDING=true -e VIRTUAL_HOST=app1.yourdomain yourcontainer
- Portainer is also launched to provide the dashboard for the docker containers:
docker run --name portainer --restart=always -v ~/portainer:/data -d -e PROXY_ADDRESS_FORWARDING=true -e VIRTUAL_HOST=portainer.yourdomain portainer/portainer -H tcp://yourdockerip:2376
So basically when some request (subdomain) arrives to nginx, it automatically redirects to the angular container app (referenced by appX.yourdomain). The best thing is that jwilder/nginx-proxy automatically update the nginx.conf when the different containers start. Our microservices architecture are implemented in Spring (autodeployment) so I include here how you can build the container with angular and nginx, but I guess you already solved this. I would also consider to use docker-compose.
Solution 2
the problem is: 8080 and 8081 containers can open resources like localhost:8080/styles.css or localhost:8080/bundle.js. but with current configuration they get localhost:8080/app1/styles.css requests instead. try adding rewrite /?app1/(.*)$ /$1 break;
rule to reverse proxy, so they would get right requests
Related videos on Youtube
Daniel Ostheimer
Updated on June 04, 2022Comments
-
Daniel Ostheimer almost 2 years
I'm currently trying to create a reverse proxy for two Angular apps. I want the apps to be both accessible through the 443 port of the docker host with SSL enabled (like https://192.168.x.x/app1 and https://192.168.x.x/app2), so that the users don't have to type in the port numbers for each app.
My setting is, that every part of the application runs within its own Docker container: - Container 1: Angular App 1 (Port 80 exposed to host on port 8080) - Container 2: Angular App 2 (Port 80 exposed to host on port Port 8081) - Container 3: Reverse Proxy (Port 443 exposed)
Both Angular apps and the reverse proxy are running on nginx. The apps are build like that:
ng build --prod --base-href /app1/ --deploy-url /app1/
The nginx setting of the apps is like that:
server { listen 80; sendfile on; default_type application/octet-stream; gzip on; gzip_http_version 1.1; gzip_disable "MSIE [1-6]\."; gzip_min_length 256; gzip_vary on; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_comp_level 9; root /usr/share/nginx/html; index index.html index.htm; location / { try_files $uri $uri/ /index.html =404; } }
The nginx configuration of the reverse proxy is like that:
server { listen 443; ssl on; ssl_certificate /etc/nginx/certs/domaincertificate.cer; ssl_certificate_key /etc/nginx/certs/domain.key; location /app1/ { proxy_pass http://192.168.x.x:8080; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; } location /app2/ { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; proxy_pass http://192.168.x.x:8081; } }
If I try to open the app on the url 'https://192.168.x.x/app1', the app is reached, but I get error messages for all static files 'Uncaught SyntaxError: Unexpected token <': Errormessages from chrome
It seems, that instead of the static js and css files, the index.html of the app is returned. I believe that this is a problem of the nginx config of the apps themselves.
I have spent quite a time trying to figure out how to solve that problem, but no luck yet. I hope that someone here can help me with that.
-
David about 5 yearsI have the same error. Any idea?
-
FlavorScape about 5 yearsso the problem was it was in a subdirectory inside another angular app, and the proxy_pass was URL rewriting, however the app was "loading" so with the addition of a deployUrl and baseHref "hack" because it doesn't work as expected, the app can load. the problem is I had to add the /basepath/ prefix to all my routes because of undesired base href conflict with how the proxy_pass altered the path.
-
-
user2484998 over 2 yearsWhen you talk about angular container, will become a contanier with a ngnix or how can you expose the internal url's ?