sudo start orkohunter.net

24 hours of pure head scratching on VPS

A screenshot of the home page

My GitHub student pack expired over a year ago and I was left with GitHub pages for hosting my webpage. It was only after creating a web app which analyzes and lists the dependencies of a Python package, I was in dire need of a server. I spinned a DigitalOcean server and hacked into the DO tutorials. I thought why not write the steps somewhere. I do these things mainly because I know I’ll end up doing some crazy stuff and will need the tutorial myself sometime in the future.

I am using

Ubuntu 14.04 LTS (because of the last LTS version with upstart)

nginx (because apache2 has too many configurations !)

Flask (Django is heavy, Flask is ❤)

uWSGI (because that works and I don’t have much idea what that means)

Purchase a VPS (Virtual Private Server) from either DigitalOcean or Amazon AWS. Try to look for educational offers, students get initial months free on both. Do the initial server setup and few workarounds if you are behind Proxy.

Now almost all of the steps ahead are referred from the original DO tutorial but I am rewriting it because they have not emphasised on the common mistakes people make. I won’t be offering explanations at all places, so please refer the original tutorial for all your queries.

Using Python 3

You are probably missing out a lot if you’re stuck with Ubuntu’s default Python version that is 2.7. See Aaron Meurer’s slides for some motivation for what I’m about to do know.

# Check the default Python's version
➜ python --version
2.7.12
# Check the location of the executable
➜ which python
/usr/bin/python
# Remove the executable and create a symbolic link of Python 3
➜ sudo rm /usr/bin/python
➜ sudo ln -s /usr/bin/python3 /usr/bin/python
# Peace !
➜ python --version
Python 3.5.2

You can revert the steps any time by removing and creating a symlink of /usr/bin/python2.7 in the same location.

Installing pip

pip is the python package manager for Python 2. pip3 is the python package manager for Python 3.

➜ sudo apt-get install python3-pip

After pip3 is installed, create a symlink of pip3 as pip.

➜ which pip3
/usr/local/bin/pip3
➜ sudo ln -s /usr/local/bin/pip3 /usr/local/bin/pip

Note that I shall not be using virtualenv in this tutorial. This is because I personally never felt the requirement. Although it’s a great tool and method of development.

Setting up the Flask application

If you think learning Python is easy, try Flask ! If you think Python code can not be shorter, try Flask ! If you think web servers and RESTful APIs are not for beginners, try Flask !

Here is the source code : https://github.com/OrkoHunter/orkohunter.net

Note the only two files required for configuration is app.py and wsgi.py.

Installing and using uwsgi

Some installations

➜ sudo pip install uwsgi
➜ sudo pip install -r require

Navigate to the root of your project and run

uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi

Try visiting http://<your_ip>:8000, you can see your website live. :)

In the logs of the above command, you can find several warnings and the possibilities of improvements. Well of course, we need them in the long run.

Create a uWSGI configuration file myproject.ini in the root of the project.

[uwsgi]
module = wsgi

master = true
processes = 5

socket = myproject.sock
chmod-socket = 666
vacuum = true

die-on-term = true

Again, refer to the original tutorial for the explanations. But, use 666 instead of 660, else you’ll be scratching your head for long. myproject.sock is a socket file which will pass requests from outside world to our flask application. We’ll be using nginx which will act as a proxy for that file for more power.

Using Upstart

Upstart is used for starting processes on boot. Create and open /etc/init/myproject.confand write

description "uWSGI server instance configured to serve myproject"

start on runlevel [2345]
stop on runlevel [!2345]
respawn
setuid user
chdir /home/user/myproject
exec uwsgi --ini myproject.ini
--socket unix:orkohunter.net.sock

Replace user and myproject with your username and project name.

Try running

sudo start myproject

and that will create the process and the socket file will now be created. We now need a server to expose the socket to port 80.

Nginx

Engine-X

Install nginx with apt-get. Create and edit /etc/nginx/sites-available/myproject file. Add the following lines to it

server {
listen 80;
server_name server_domain_or_IP;

location / {
include uwsgi_params;
uwsgi_pass unix:/home/user/myproject/myproject.sock;
}
}

That is it. Create a symlink to the sites-enabled directory.

sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

Check the syntax by sudo nginx -t. Restart the server

sudo nginx restart

The DigitalOcean tutorial ends here and your website should be live. But I’d like to continue with some of my personal points.


Logs

You need to see the logs for debugging. While the nginx and upstart logs are stored in /var/log/<dir>, they do not contain the errors caused in the Flask app. Open your myproject.ini file and add the following line to it

logto = /var/log/uwsgi/error.log

You’re good to see the Python logs now !

Environment variables

I am an open source fanatic and hence for privacy, I declare secret keys as environment variables. The best way to declare an environment variable is to add them in the Upstart configuration file. Open your /etc/init/myproject.conf file and add

env APP_SECRET_KEY="not so secret"

to declare the APP_SECRET_KEY environment variable. In Python, you can use this variable as os.environ["APP_SECRET_KEY"].

Now, you need to do

sudo restart myproject

That’s all for now. Cheers !