Home > Software design >  Flask API & nginx alongside each other
Flask API & nginx alongside each other

Time:02-14

I have a server that I'm trying to set up. I have a Flask server that needs to run on api.domain.com, while I have other subdomains pointing to the server. I have one problem. 2/3 subdomains have no problem using nginx. Meanwhile, my script tries to bind to port 80 on the same machine, therefore failing. Is there a way I can bind my Flask REST script to port 80 ONLY for the subdomain 'api'? My current config is:

server {
        server_name api.domain.me;
        location / {
            error_page 404 /404.html;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_max_temp_file_size 0;
            proxy_pass http://127.0.0.1:5050/;
            proxy_cache off;
            proxy_read_timeout 240s;
    }
}

There's a little problem though, nginx likes to turn all POST requests into GET requests, any ideas? Thanks!

CodePudding user response:

There is no way binding two different applications on port 80 at the same time.

I would set up your api like this:

Bind your Flask API to Port 8080. On NGINX you can configure you subdomain pointing to your Flask Application

upstream flask_app {
  server 127.0.0.1:8080;
}


sever {
  listen 80;
  server_name api.domain.com;

  location / {
    proxy_pass http://flask_app/;
    proxy_set_header Host $host;
  }
}

CodePudding user response:

I actually found out after a bit of diagnosis.

server {
    if ($host = api.domain.me) {
        return 301 https://$host
    }
    # managed by Certbot

had to become:

server {
    if ($host = api.domain.me) {
        return 497 '{"code":"497", "text": "The client has made a HTTP request to a port listening for HTTPS requests"}';
    }

Because Certbot tries to upgrade the request to https but the HTTP method gets changed to GET because of the 301 response code.

  • Related