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