I am struggling to find a working example of a custom Addon that implements ingress and serves static angular 10 files via nginx. So far, I am able to configure the addon ingress + nginx server to serve static html files (they just work). However, when I put the angular compiled /dist files into the root file folder of nginx, I start having problems. It looks like the index.htmk is loaded but then any attempt to load js/css fails. I suspect something with routing or service worker is not working as expected.
I’ve also created a simple Hello-World addon based on an angular 11 hello world + nginx server via addon ingress, to showcase the problem. Find it here
Is there anyone who can help to figure this out? I believe this would be helpful to a number of people.
I was struggling with the same topic and decided to change the angular application and the web server. The topic is closed, but I didn’t found a solution which worked for me:
This is the issue:
You need to run the angular application in a subdirectory which is not known at deployment time.
So, you have to set it at boot time. Angular doesn’t support this out of the box.
The client needs to “know” the base href because all subsequent html calls.
This can be achieved by replacing the " element in index.html
This will already enable reading of the static angular files.
In order to achieve the same for the http Client calls on the client, the base url must be prepended to the API calls.
This is what needs to be done:
set the HashLocationStrategy by setting useHash: true
It builds # url’s instead of path url’s they are not processed by the server
On the server you need to read the X-Ingress-Path from the request header and use it to update the base url
private setIngressUrl(req: Request) {
let h = req.header("X-Ingress-Path");
this.ingressUrl = h ? h : "/";
}
private sendIndexFile(req: Request, res: express.Response) {
this.setIngressUrl(req);
let dir = this.getDirectoryForLanguage(req);
let file = join(this.angulardir, dir, "index.html");
let content = fs.readFileSync(file).toString();
let htmlDom = parse(content.toString());
if (this.ingressUrl && content && htmlDom) {
let base = htmlDom.querySelector("base");
base?.setAttribute("href", join("/", this.ingressUrl, "/"));
content = htmlDom.toString();
res.status(200).setHeader("Content-Type", "text/html").send(htmlDom.toString());
} else res.status(401).setHeader("Content-Type", "text/html").send("Invalid index.html file ");
}
The approach has the following advantages:
One application in the docker file (nginx is not required)
The same docker file for Homeassistant addon and Standalone (If the X-Ingress-Path is not available in the header, nothing will happen
Only a few changes in the angular and in express application are required
I tried the nginx approach also, but I struggled when it came to angular routing.
I am still not convinced, that it works without modifications in angular.
Hi all,
I’m trying to develop an addon for Hassio as well with Angular and I’m running into similar troubles. @albertogeniola I tried to follow your example repository but I didn’t get it to work.
In practice using your example repo as guide, I get the following snippet of config inside my addon /etc/nginx.conf:
When I open the web interface for my addon, I see an empty page and in the Chrome Console I see all requests to fetch the polyfill and main.js files are 404ing.
@vovo500 ,
looking at your post at step#3, if I understand correctly you’re using a Nodejs server to serve the Angular app right?
I was trying to use the nginx web server instead having the nginx listening on port 8099 (ingress port) and trying to get some rewrite rule working fine (just like @albertogeniola did 3 years ago)…