Home > Net >  Nginx routing on 2 angular app under Docker Compose
Nginx routing on 2 angular app under Docker Compose

Time:08-24

I have 2 angular app bundled in 2 separate docker images based on nginx image:

FROM node:14-alpine as build
WORKDIR /app

RUN npm install -g @angular/cli

COPY FrontEnd1/package*.json ./
RUN npm install
COPY FrontEnd1/. ./
RUN npm run build -- --configuration=production

FROM nginx as runtime

COPY --from=build /app/dist/FrontEnd1 /usr/share/nginx/html
VOLUME /usr/share/nginx/html/assets/configuration/

The second angular app have exactly the same Dockerfile (except it is FrontEnd2). I deploy it using docker compose:

version: "3"
services:
  proxy:
    image: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:      
      - $STORAGE_FOLDER/nginx/conf/:/etc/nginx/conf.d/:rw
    restart: always

  public:
    image: frontend1

  creator:
    image: frontend2

Then, I push the following nginx file to define the routes:

upstream creator {
    server creator;
}

upstream public {
    server public;
}

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

    server_name localhost;

    location /creator {
        proxy_pass http://creator;
    }

    location / {
        proxy_pass http://public;
    }
}

It work perfectly for / route, but not for /creator route. The request comes with /creator part in the url to the frontend2 subnginx which return 404.

I've tried to add a trailing / :

    location /creator {
        proxy_pass http://creator/;
    }

But I get a 304 in the sub nginx and nothing is returned.

I tried to add another trailing / on the location:

    location /creator/ {
        proxy_pass http://creator/;
    }

And I get the same 304 with no result.

What is wrong with my code?

CodePudding user response:

For my need, the solution is in Angular application: I need to use 2 parameters to achieve my goal:

APP_BASE_HREF can be set in build time (this will be my case) or runtime by declaring APP_BASE_REF provider or set it in index.html:

<head>
   <base href="/">

to

<head>
   <base href="/creator">

But this will handle only the routes of the application: adding automatically /creator in front or each my url (It adds /creator#/ in front of each of my url, I think something should be tweaked to avoid the extra '#' char, but I will see it later).

Next we should use a build setting to change the path of the scripts in index.html.

From this:

<script src="runtime.xxxxxxxxxxx.js" type="module"></script>

To this:

<script src="creator/runtime.xxxxxxxxxxx.js" type="module"></script>

In order nginx will correcly route the request from index.html. Warning: the /creator folder doesn't exist in the produded files, it is only a route for nginx.

This is done by adding the --deploy-url=/creator parameter in the build. So yes, there is a deployment parameter in the final image. The image is not deployable everywhere anymore.

Then, we must use this path for each assets loaded in the application. To retreive the path, I used code from this post Angular CLI build using base-href and deploy-url to access assets on CDN

Adding a provider in app.module.ts

{ 
  provide: DEPLOY_URL, 
  useValue: deployUrl, 
},

Allows to inject the deployUrl in my components:

constructor(
   @Inject(DEPLOY_URL) public baseHref:string)

that I can use in the html file.

And finally, it works (on my computer

  • Related