I’m trying to deploy my frontend client application and backend API on the same domain and I want the frontend on the base path: /
However, I realized that the frontend and the backend need two different rewrite-target to accomplish this.
front-end works with:
nginx.ingress.kubernetes.io/rewrite-target: /
while the backend works with:
nginx.ingress.kubernetes.io/rewrite-target: /$2
I tried using two different ingress services in order to accommodate different rewrite-target, but that fails because the host was the same domain.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
namespace: test
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-staging
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/add-base-url: "true"
nginx.ingress.kubernetes.io/service-upstream: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
nginx.ingress.kubernetes.io/proxy-buffering: "on"
nginx.ingress.kubernetes.io/proxy-buffers-number: "4"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "server: hide";
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "X-Xss-Protection: 1";
spec:
tls:
- hosts:
- test.eastus.cloudapp.azure.com
secretName: tls-secret
rules:
- host: test.eastus.cloudapp.azure.com
http:
paths:
- backend:
serviceName: webapp
servicePort: 80
path: /
- backend:
serviceName: api
servicePort: 80
path: /api(/|$)(.*)
I know I can make both work with the same rewrite-target /$2
if I change the frontend path to path: /app(/|$)(.*) but I don’t want to that except it is the only option.
Is there a way for me to better configure a single ingress to work for 2 different rewrite-target?
3
Answers
I don’t know would you take it or not but it can a be solution. You can use two ingress for achieving your target. Each one will use different annotations. It will work fine.
Just as like your current ingress yaml, make another yaml and put two different annotations in them and also put your front-end and back-end in them separately. host (
host: test.eastus.cloudapp.azure.com
) will be same as you provided here.Ingress with API version networking.k8s.io/v1 with k8s version 1.19+ can solve your problem. I have given an example below.
According to kubernetes documentation:
So, when you are looking for a resource located at path "/home.html", it only matches with your frontend service. But when you are looking for a resource located at path "/api/something" then it matches both service. But it will go to backend service always because of maximum path match stated above.
[My original answer was closed on a technicality by @Samuel Liew – Samuel, the answer was actually a better fit for this question since it specifically addresses the issue of not getting a blank page on refresh when using Vue frontend routing]
TLDR: The trick is to use
"nginx.ingress.kubernetes.io/configuration-snippet" = "if ($request_uri !~* ^/(api|assets)) { rewrite ^/.*$ / break; }"
which rewrites all paths except/api
and/assets
. The other thing to point out, I put my favicon within theassets
folder and then<link rel="shortcut icon" href="/assets/favicon.ico">
inmain.ts
For the full solution, see: https://stackoverflow.com/a/75913365/7182570