Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am currently running nginx on port 80, with the configured server names as example.com and www.example.com.

I also have a Flask application that I would like to have accessible through port 80, but using the hostname app.example.com.

Since nginx is already using port 80, how exactly would I route app.example.com requests to Flask application?

Note that the server only has one IPv4 address.

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

Should be fairly easy.

Make sure that Flask itself is running on a port other than 80.

Then use NginX as a reverse proxy (and webserver) to handle, a subdomain for app.example.com, and secondly handle that as a proxy for localhost:8080 (or wherever your flask application is bound).

upstream flask  {
      server 127.0.0.1:8080; #Flask
}

server {
    listen       YOUR_PUBLIC_IP:80;
    server_name  app.example.com;

location / {
     proxy_pass  http://flask;
     proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
     proxy_redirect off;
     proxy_buffering off;
     proxy_set_header        Host            $host;
     proxy_set_header        X-Real-IP       $remote_addr;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
   }

}

You can have many server{} blocks, all on port 80, as long as server_name varies, and use them just like Apache VirtualHosts.

share|improve this answer
add comment

It's not a good idea to directly serve the application on port 80. It's much better to have a standard HTTP server listening on port 80 and forwarding requests to your Python (Flask) application's WSGI server.

You should configure nginx to send all requests for app.example.com to your WSGI (Python Application Server). This way the requests for http://example.com:80 will be served directly by nginx and all requests for the virtual host app.example.com:80 will be forwarded to your Python Application server. Depending on your preference you can run your Python/Flask application using either uWSGI or gunicorn.

To configure app.example.com as a virtual host you will need to create a file (eg. /etc/nginx/sites-available/app.example.com if you're using a Debian based distro) that will contain something like this:

server { 
  server_name app.example.com; 
  access_log /var/log/nginx/app-access.log; 
  error_log /var/log/nginx/app-error.log; 
  location /static { 
    root /var/www/app.example.com/static; # adjust to fit your path here 
  } 
  location / { 
    uwsgi_pass unix:/tmp/uwsgi_app.sock; 
    include /etc/nginx/conf.d/uwsgi_params; 
  } 
}

The content of the location / section need to be adjusted, depending on the specific WSGI server you choose to use - see bellow.

Then you need to symlink the new virtual host config to sites-enabled and restart nginx:

ln -sf /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
/etc/init.d/nginx restart

See this document for more information about configuring nginx to serve multiple sites (virtual hosts) on the same IP address and TCP port.

Here are two blog entries describing how to configure nginx with uWSGI: Deploying Flask With Nginx and uWSGI Setting up Flask with nginx and uWSGI. If you prefer gunicorn (a Python WSGI port of Ruby's unicorn Application server) you can check this SO question: Running a Flask App with nginx and gunicorn and Serving Flask Applications with Nginx and gunicorn

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.