<p>While working with minikube ingress, I have to write <code>nginx.ingress.kubernetes.io/rewrite-target: /$1</code>. I have been trying hard to understand why we need this annotation and how to use it.</p>
<p>I know that the <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rewrite" rel="noreferrer">doc</a> says the following:</p>
<blockquote>
<p>In some scenarios the exposed URL in the backend service differs from the specified path in the Ingress rule. Without a rewrite any request will return 404. Set the annotation nginx.ingress.kubernetes.io/rewrite-target to the path expected by the service.</p>
</blockquote>
<p>But I am not able to get the exact point of what exactly <code>the exposed URL in the backend service differs from the specified path in the Ingress rule</code> means. I am not able to get the idea clearly.</p>
<p>Further, upon trying to execute ingress file with services:</p>
<p>code 1:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /
            pathType: Prefix 
            backend:
              service:
                name: example-service
                port:
                  number: 80
</code></pre>
<p>code 2:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /
            pathType: Prefix 
            backend:
              service:
                name: example-service
                port:
                  number: 80
</code></pre>
<p>code 3:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /index
            pathType: Prefix 
            backend:
              service:
                name: example-service
                port:
                  number: 80
</code></pre>
<p>what exactly is the difference between each pair of the above 3 code snippets with respect to rewrite-target and path mentioned above?</p>
<p>PS: I'm new to minikube and trying to figure out the exact way things work. Please help.</p>

<p>I don't know if things changes with new versions of the Ingress resource or with new versions of the Nginx Ingress Controller, but this is how I think it works.</p>
<p>Suppose I want to serve 2 different web applications under the same domain, with a Ingress.</p>
<ul>
<li>App A is expecting requests under <code>/</code></li>
<li>App B is expecting requests under <code>/</code></li>
</ul>
<p>So, both Apps are expecting their requests directly under root, which (at first glance) seems to make them impossible to be served at the same domain.</p>
<p>Except, with rewrite targets, I can. I could just serve them under a different path, but rewrite the target to <code>/</code></p>
<ul>
<li>Serve App A under <code>myexample.com/aaa/</code></li>
<li>Serve App B under <code>myexample.com/bbb/</code></li>
</ul>
<p>And add a rewrite target to remove the first part of the path. This is just an example of what a rewrite target can be used for, it simply makes you able to serve an application under a different path of the one expected by the app itself.</p>
<p>Example of the ingress:</p>
<pre><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /aaa(/|$)(.*)
            pathType: Prefix 
            backend:
              service:
                name: app-a
                port:
                  number: 80
          - path: /bbb(/|$)(.*)
            pathType: Prefix 
            backend:
              service:
                name: app-b
                port:
                  number: 80
</code></pre>
<p><strong>Notice that</strong>, while this works pretty well on Rest API and similar things, it may work less well on web pages, because a web page could try to load resources at a different path (for example if it does not use relative paths). This is why (usually) frontend applications needs to know on which path they are being served under a domain.</p>
<hr />
<p>Regarding the syntax of rewrite targets, I'll take as example the Ingress I wrote above. There are a couple things to take into consideration:</p>
<ul>
<li>path</li>
<li>pathType</li>
<li>rewrite-target</li>
</ul>
<p>Let's start with <code>path</code> and <code>pathType</code> interactions. With the path I can define where to serve my services. Depending on the <code>pathType</code>, it may be just a <code>Prefix</code> of the whole path, the <code>Exact</code> path, or it can depends on the Ingress Controller (aka <code>ImplementationSpecific</code>). Everything is nicely explain in the documentation with a long table of examples ( <a href="https://kubernetes.io/docs/concepts/services-networking/ingress/#examples" rel="noreferrer">https://kubernetes.io/docs/concepts/services-networking/ingress/#examples</a> )</p>
<p>I can do almost everything just with path and pathType, except if the applications I want to serve are expecting to be served at different paths from the ones specified in the Ingress; this is when <code>rewrite-target</code> comes into play.</p>
<p>Like in the example above, I can use <code>rewrite-target</code> to serve an application under a different path from the one expected, composing the url as I want. I can also use regex and capture groups (this is what <code>$1</code>, <code>$2</code> and so on are)</p>
<p>For example, if I write <code>path: /bbb(/|$)(.*)</code> I mean that this path will match everything under /bbb, with or without a / after bbb. And if I then write <code>rewrite-target: /$2</code> I'm meaning that requests will be rewritten to substitute <code>/bbb</code> with <code>/</code> and then take the second capture group (which means the second regex expression, <code>(.*)</code> )</p>
<p>The documentation explains it pretty well, even if it makes still use of the old Ingress resource ( <a href="https://kubernetes.github.io/ingress-nginx/examples/rewrite/" rel="noreferrer">https://kubernetes.github.io/ingress-nginx/examples/rewrite/</a> )</p>
