0

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?

nimbusparis
  • 391
  • 5
  • 16
  • [According to this cross-site dupe](https://serverfault.com/questions/562756/how-to-remove-the-path-with-an-nginx-proxy-pass), the solution with both location and proxy_pass having trailing slash should work. – STerliakov Aug 18 '22 at 14:00
  • @SUTerliakov It works, but I have routing issues now, I think I should handle the sub path in each image by Angular – nimbusparis Aug 18 '22 at 15:45

1 Answers1

1

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 ).

Next step would be to deploy https certificate using certbot, but it is another story!

General Grievance
  • 4,555
  • 31
  • 31
  • 45
nimbusparis
  • 391
  • 5
  • 16