swiss_knight
swiss_knight

Reputation: 7781

Docker Flask app behind nginx reverse-proxy sending 404

Tl;DR:
I have a running Flask application in a docker container. When I set up a nginx reverse proxy on the host machine in order to avoid having to enter the port number in the URL, the app send a 404 each time I hit the homepage at the defined nginx location. Why?

Context

I've got a prototype Flask app running as:

flask run --host 0.0.0.0 --port 5000

It's dockerized and is exposed on port 8080 in a compose file:

ports:
  - "8080:5000"

Everything is working fine and when I hit the homepage at http://my-server.org:8080, the server happily says:

web_1  | in route /
web_1  | 166.24.119.203 - - [24/Sep/2041 10:29:20] "GET / HTTP/1.1" 200 -
web_1  | 166.24.119.203 - - [24/Sep/2041 10:29:21] "GET /static/css/style.css HTTP/1.1" 200 -
web_1  | 166.24.119.203 - - [24/Sep/2041 10:29:21] "GET /static/favicon.ico HTTP/1.1" 200 -

Now, in order to avoid having to enter the port in the URL, I've setup a simple MWE nginx reverse-proxy config file in /etc/nginx/sites-available/ on the host machine (not yet dockerized for simplicity) and which is automatically sym-linked in sites-enabled/. This file contains the following:

server {
    listen 80;
    listen [::]:80;

    server_name my-server.org;

    location /my-app {
        proxy_pass http://127.0.0.1:8080;
    }
}

Please, note that nginx is properly running:

# service nginx status
● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2021-01-30 10:48:17 CET; 54min ago
   ...

Now, each time I hit the homepage at http://my-server.org/my-app now, the server returns:

web_1  | 172.27.0.1 - - [24/Sep/2041 12:34:26] "GET /my-app HTTP/1.0" 404 -

If that can help, I noticed that the IP shown here is actually the Gateway value of the my-app_default docker network used by the service.

Question

How do I get my Flask app to properly work behind the nginx reverse-proxy?
I hope to understand enough from the answer(s) to be able to set up the same thing using gunicorn after.

Upvotes: 2

Views: 923

Answers (1)

qräbnö
qräbnö

Reputation: 3031

That

    location /my-app {
        proxy_pass http://127.0.0.1:8080;
    }

adds /my-app to http://127.0.0.1:8080.

Fix: Add a slash / after port:

    location /my-app/ {
        proxy_pass http://127.0.0.1:8080/;
    }

Yes, slash at end makes often a big difference in Nginx.

It is equivalent to:

    location /my-app/ {
        rewrite ^/my-app(.*)$ $1 last;
        proxy_pass http://127.0.0.1:8080;
    }

IIRC, but I never use it.

BTW: Normally you put the symlink in sites-enabled not in sites-available.

Upvotes: 4

Related Questions