Categories
Linux Python

Deploying a Flask app on Ubuntu: uWSGI, nginx and Upstart

Let’s get straight to the point. I have a Flask app that I want to run on Ubuntu. I shall use uwsgi and nginx. Upstart will be used to monitor the process and restart it if it’s killed or dies an untimely death.

Running the uWSGI app with nginx

It’s very easy to run Flask apps with uwsgi, just cd into the directory where your main app file exists and pass the uwsgi module name. If your main app file is called “main.py” and if your Flask app instance is called “app” inside main.py, then your uWSGI module name would be “main:app” from the directory where main.py resides.

Now, we need to configure nginx:

Here, we first need to define an upstream. We define the “flaskapp” upstream for our app. Then inside the location block, we use it as the source of our uwsgi_pass directive. It would tell nginx to connect to the uwsgi server we defined and serve as a bridge between the internet and the flask uwsgi app.

Upstarting the uWSGI process

Now, what happens if our uWSGI process dies? nginx would no longer be able to connect to the app and throw a “bad gateway” error. So we need to make sure that if the process dies from an error or somehow gets killed, it is restarted automatically. There are a few tools which can do this. Supervisord is the most popular one, Circus is also very nice. However, I like to use Upstart for cases like this. Upstart comes with Ubuntu and used by the OS for many of it’s own services. It’s easy to use, already available, reliable and most importantly – it allows me to create a service too!

To create our upstart config, we cd into “/etc/init” and create a new file named “flaskapp.conf”. Then we put the following contents in there:

Here, we’re telling Upstart to launch our app on startup and respawn whenever the process dies. We put our commands in a script block. We have defined our service, now time to fire it up. If you have any uwsgi process run with the same config, first kill them. Then run this command to start the service:

Right, you can use the usual “start|stop|restart|status” service commands with it. The service name is derived from the file name we used in “/etc/init”. The log of the process would be found in “/var/log/upstart/flaskapp.log”.

From Upstart to Systemd

Ubuntu is moving away from Upstart to systemd. Most of my apps use Ubuntu 14.04 LTS so I can still use Upstart fine. However, if your version of Ubuntu doesn’t ship Upstart, you can use systemd for similar tasks. Here’s the link: systemd for upstart users

Categories
Linux Python

Python and Django on Vagrant

Well, this is going to be another straight forward post with loads of shell commands. The background is simple, I love OS X for the many apps it offers but at the same time I always had the joy of developing on a Linux machine. I decided to use Vagrant to have one central box for my projects. I use separate vagrant boxes for complicated projects. But didn’t like the idea of having individual boxes for simple ones.

I work on Python and Django a lot. So in this post I am going to document my setup.

Vagrant File:

# I have assigned a private IP to the box
# I have assigned a hostname to it.
# I am using Ubuntu Precise Pangolin 64 bit as my base box (which I already have added)

Hosts File (/etc/hosts):

After I setup the box, I logged in using SSH:

Now, the usual Ubuntu setup.

Bash Profile in the Ubuntu machine:

# To make the Django built in server available from outside the box I need to run it on 0.0.0.0 so that it listens on all interfaces. So I added a handy alias.

# Added the virtualenv stuff to the profile

Bootstrapping a project:

Now the app would be available on: http://tardis.dev:8000

I also modify the ~/.virtualenvs//bin/postactivate script to cd into the project source directory. Saves time when I hit “workon env_name”

That’s it 🙂

Categories
Linux

Debugging MongoDB Connection Issues

I am working on a project where I connect to MongoDB from PHP using the PECL extension. Regardless of your stack, we might time to time face strange issues when our clients can’t connect to the mongodb server. In this post, I would document what I did in my case.

First test if the mongodb server can be connected to. Use the “mongo” shell client.

If the connection succeeds, then the server is definitely reachable. You have made some mistakes in configuring your client. A very common mistake is having a malformed connection URI. So double check if you typed in your host, port and other details properly in the connection string.

If the above fails, that means the server is not responding. To begin with, try restarting it.

If the server started well, try again. Still connection failed? OK, the server might be damaged. How about checking the log files?

Nothing interesting? Or do not understand the format? Well, then let’s try blindly repairing the server:

Your problem should be resolved by now. But if it doesn’t solve the issue, your problem is not a common one. Try Googling further or asking on StackOverflow or other programming forums.