title: Modify $request_uri in Nginx
body: <p>I have multiple apps running on the <code>Nginx</code> server:</p>
  
  <pre><code>http://example.com/app1/ctrl/view
  http://example.com/app2/ctrl/view
  ...
  </code></pre>
  
  <p>I would like to assign these apps DNS like so:</p>
  
  <pre><code>http://app1.example.com
  http://app2.example.com
  ...
  </code></pre>
  
  <p>For that I've tried the following server block:</p>
  
  <pre><code>server {
          listen 80;
          server_name app1.example.com;
  
          location / {
              proxy_pass http://example.com/app1/$request_uri;
          }
  }
  </code></pre>
  
  <p>If a user is not logged in, my app would redirect to URI:</p>
  
  <pre><code>app1/ctrl/user/login?_next=/app/ctrl/view
  </code></pre>
  
  <p>Essentially <code>$request_uri</code> becomes (Note doubled <em>app1</em> instance):</p>
  
  <pre><code>app1/app1/ctrl/user/login?_next=/app/ctrl/view
  </code></pre>
  
  <p>Is there a convenient way to modify <code>$request_uri</code> or a better method to get around this problem?</p>
  
  <p><strong><em>EDIT1</em></strong></p>
  
  <p>It seems I've solved my problem with the following server block:</p>
  
  <pre><code>server {
          listen 80;
          server_name app1.example.com;
  
          location / {
  
              set $new_request_uri $request_uri;
  
              if ($request_uri ~ ^/app1/(.+)$) {
                  set $new_request_uri $1;
              }
  
              proxy_pass http://example.com/app1/$new_request_uri;
          }
  }
  </code></pre>
  
  <p>If someone knows a better (or proper "<code>Nginx</code>") way to do this please don't hesitate to post an answer.</p>
  
  <p><strong><em>EDIT2</em></strong></p>
  
  <p>Based on the comments I've also tried the following: </p>
  
  <pre><code>server {
          listen 80;
          server_name app1.example.com;
  
          location / {
              proxy_pass http://example.com/app1/;
              proxy_redirect /app1/ /;
          }
  
          location ~ ^/app1/(.+)$ {
              return 301 http://$server_name/$1;
          }
  }
  </code></pre>
  
  <p>This one looks better on screen, as it eliminates <em>app1</em> instance in the <code>$request_uri</code> part completely, but you must have two <code>location</code> blocks.</p>
  
  <p><strong><em>EDIT3</em></strong></p>
  
  <p>The most efficient way to solve my problem apparently is as shown in this config:</p>
  
  <pre><code>server {
          listen 80;
          server_name app1.example.com;
  
          location / {
              proxy_pass http://example.com/app1/;
              proxy_redirect /app1/ /;
          }
  
          location /app1/ {
              rewrite ^/app1(.+) $1 permanent;
          }
  }
  </code></pre>
  
  <p>This is due to the fact, that <code>Nginx</code> always tries to match the longest <code>prefix</code> first and then (if <code>^~</code> modifier is not present) starts sequentially processing <code>regexes</code> until the first <code>regex match</code> is found. Essentially this means that all <code>regexes</code> are processed on every request, regardless if any of these find a match, therefore it's better to have <code>regexes</code> inside <code>location</code> directives.</p>