<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>OK, sadly I was pre-mature in my explanation and claim of
      success, although the trailing slash was clearly an issue. Now I
      can use the application fine in the open browser  which I can see
      did implement my changes because I can move around in the app
      normally. <br>
    </p>
    <p>But I get too many redirects with other browsers or other
      instances of the same browser, which suggests to me that something
      was cached at some point in my testing that is allowing it to
      work. curl returns a 301 and firefox returns a too many redirects.</p>
    <p>So not solved yet unfortunately but progress has been made.<br>
    </p>
    <div class="moz-forward-container"><br>
      <br>
      -------- Forwarded Message --------
      <table class="moz-email-headers-table" cellspacing="0"
        cellpadding="0" border="0">
        <tbody>
          <tr>
            <th valign="BASELINE" nowrap="nowrap" align="RIGHT">Subject:
            </th>
            <td>Re: soooo close: nginx gunicorn flask directory stripped
              from links - SOLVED</td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap="nowrap" align="RIGHT">Date: </th>
            <td>Fri, 16 Sep 2022 11:57:55 -0600</td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap="nowrap" align="RIGHT">From: </th>
            <td>Brian Carey <a class="moz-txt-link-rfc2396E" href="mailto:biscotty666@gmail.com"><biscotty666@gmail.com></a></td>
          </tr>
          <tr>
            <th valign="BASELINE" nowrap="nowrap" align="RIGHT">To: </th>
            <td>Francis Daly <a class="moz-txt-link-rfc2396E" href="mailto:francis@daoine.org"><francis@daoine.org></a></td>
          </tr>
        </tbody>
      </table>
      <br>
      <br>
      Hi,<br>
      <br>
      I believe that if something isn't working that should be the usual
      answer is very simple. In my case I forgot the trailing slash at
      the end of the proxy_pass directive. otoh I did learn a lot partly
      thanks to my "conversation" with you.<br>
      <br>
      To clarify one question below, in my case redirects were working
      correctly, which are the ones using url_for(). It was the
      render_template calls which were failing.<br>
      <br>
      Anyway I really appreciate the thoroughness of your responses.<br>
      <br>
      Cheers,<br>
      <br>
      Brian<br>
      <br>
      On 9/16/22 10:17, Francis Daly wrote:<br>
      <blockquote type="cite">On Fri, Sep 16, 2022 at 09:38:54AM -0600,
        Brian Carey wrote:<br>
        <br>
        Hi there,<br>
        <br>
        <blockquote type="cite">I'm trying to implement this suggestion:<br>
          <br>
          You can possibly / potentially avoid all of that, if you are
          happy<br>
          to deploy your app athttp://127.0.0.1:8000/app/ instead of at<br>
          <a class="moz-txt-link-freetext" href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a><br>
        </blockquote>
        I think I did follow that with: I'm presuming that it is
        possible to<br>
        deploy a flask app somewhere other than the root of the web
        service.<br>
        <br>
        ;-)<br>
        <br>
        It will be entirely a flask / gunicorn /
        something-other-than-nginx thing.<br>
        <br>
        After that is working, your nginx config will be of the form<br>
        <br>
        location ^~ /this-prefix/ { proxy_pass http://ip:port; }<br>
        <br>
        with no / or anything else after the port.<br>
        <br>
        <blockquote type="cite">1. adding a directory level, ie. moving
          /var/www/application to<br>
          /var/www/application/application. This seemed to have no
          effect at all.<br>
        </blockquote>
        If nginx is doing proxy_pass, it does not care about the
        filesystem. I<br>
        don't know what gunicorn does with that.<br>
        <br>
        <blockquote type="cite">2. modifying gunicorn unit file to: 
          --bind 0.0.0.0:8000/app. No effect<br>
        </blockquote>
        I think I'd expect that to fail; unless "bind" is clever enough
        to stop<br>
        reading when it knows the IP and port.<br>
        <br>
        <blockquote type="cite">3. changing nginx conf proxy_pass
          declaration to localhost:8000/app. This<br>
          broke everything.<br>
        </blockquote>
        That can work, in different circumstances -- it would need the
        gunicorn<br>
        setup to know what to do with requests that start /app. And once
        you do<br>
        the SCRIPT_NAME thing for gunicorn (described below), then it
        does know<br>
        that -- but the suggested nginx config does not duplicate the
        "location"<br>
        in the "proxy_pass".<br>
        <br>
        <blockquote type="cite">4. I did try 2 & 3 together but that
          broke it.<br>
        </blockquote>
        Yes, "3" with the eventual "two-step" (below) will break.<br>
        <br>
        <blockquote type="cite">4. In the app I removed initial slash in
          @app.routes, no joy<br>
        </blockquote>
        That sounds like a flask/gunicorn thing; I'm lost there ;-)<br>
        <br>
        <blockquote type="cite">Can you tell me where/how I can effect
          this change?<br>
        </blockquote>
        Some web searching points to<br>
        <a class="moz-txt-link-freetext" href="https://github.com/benoitc/gunicorn/issues/1513">https://github.com/benoitc/gunicorn/issues/1513</a> and<br>
        <a class="moz-txt-link-freetext" href="https://dlukes.github.io/flask-wsgi-url-prefix.html">https://dlukes.github.io/flask-wsgi-url-prefix.html</a>, which seem
        to<br>
        suggest a two-step thing, the first of which you might be doing
        already:<br>
        <br>
        * in your code, use url_for() for internal links:<br>
        <br>
        """<br>
        instead of writing href="/login" in your templates or
        redirect("/login")<br>
        in your view functions, write href="{{ url_for('login_func') }}"<br>
        and redirect(url_for("login_func")). This will make sure the
        URLs are<br>
        correctly prefixed with SCRIPT_NAME, if applicable.<br>
        """<br>
        <br>
        * when you start gunicorn, make the environment variable
        SCRIPT_NAME<br>
        have the value "/this-prefix"<br>
        <br>
        The second url has a "minimum working example" of an "app.py"
        shown at<br>
        <a class="moz-txt-link-freetext" href="https://dlukes.github.io/flask-wsgi-url-prefix.html#mwe">https://dlukes.github.io/flask-wsgi-url-prefix.html#mwe</a><br>
        <br>
        Stick that behind an nginx, and you should be able to access<br>
        <a class="moz-txt-link-freetext" href="http://nginx/app/">http://nginx/app/</a> or <a class="moz-txt-link-freetext" href="http://localhost:8000/app/">http://localhost:8000/app/</a>. (But probably
        not<br>
        <a class="moz-txt-link-freetext" href="http://localhost:8000/">http://localhost:8000/</a>.)<br>
        <br>
        And if you want to run a completely separate "app2", you can<br>
        have <a class="moz-txt-link-freetext" href="http://nginx/app2/">http://nginx/app2/</a> giving the same response as (for
        example)<br>
        <a class="moz-txt-link-freetext" href="http://localhost:8001/app2/">http://localhost:8001/app2/</a>.<br>
        <br>
        Good luck with it!<br>
        <br>
        If you do find a working answer, one of us should follow-up to
        the list<br>
        with the details, so that the next person with the same problem
        will<br>
        have a better chance of a search engine pointing them to the
        answer.<br>
        <br>
        Cheers,<br>
        <br>
        f<br>
      </blockquote>
    </div>
  </body>
</html>