For someone new to application or server deployment (or any field, really), the vast assortment of commands, arguments, variables, and parameters can be overwhelming. That’s why I encourage friends and coworkers to break those daunting projects into smaller, more digestible pieces. Once they understand what is right in front of them and can relate it to their work, additional pieces can be added as the needs arise.

Sure, there are those min-maxing types that obsess over identifying the perfect way of doing everything. There’s nothing particularly wrong with this, as we should all strive for perfection. However, from my own experiences I feel that an obsession like that will actually impede progress.

Below is a command for loading uWSGI and a sample configuration file for Nginx that can be used to deploy a Flask app. This slightly more invovled than the uWSGI deployment example provided in the Flask documentation.

uWSGI

uwsgi -s /tmp/uwsgi.sock --module myapp --callable app

The first argument specifies the socket the application should bind to. In this case, a Unix socket at /tmp/uwsgi.sock. The other two arguments tell uWSGI to load the module named myapp with the callable name app.

You probably won’t see uWSGI run from the command line like this very often. Instead, configuration files are created which specify the desired settings and a daemon process manages the application, starting and stopping it as necessary.

Nginx

server {
    listen 80;
    server_name $hostname;
    root /srv/www/$hostname/myapp;

The Nginx configuration starts like a normal server block and is set to listen on port 80. However, rather than entering an actual hostname, the embedded variable $hostname is used which inserts the machine’s hostname instead.

The same thing happens when the root directory is being set. By putting the $hostname variable in the configuration, the files are much more versatile and can be reused used on other servers without having to first be modified for that particular server’s name.

location = /favicon.ico {
       alias /srv/www/$hostname/public_html/favicon.ico;
       access_log off;
       log_not_found off;
    }

When you’re digging through Nginx logs, trying to track down a particular error, the last thing you want to see are rows of favicon.ico requests. The location detective here matches requests for favicon.ico, points them to the file on the server, and doesn’t log a thing regardless of whether it failed or succeeded. This can be done with robots.txt as well to avoid some unnecessary logging.

Send requests to Flask app

    location / { try_files $uri @myapp; }

    location @myapp {
       include uwsgi_params;
       uwsgi_pass unix:/tmp/myapp.sock;
    }
}

All requests except for /favicon.ico will be going through this second location block. This block uses try_files to see if the requested file exists, before sending it to uWSGI using the named location: @myapp.

%d bloggers like this: