Bottle is my favorite micro web framework for  python.  It is well designed, allows quick prototyping and also developing web based applications.

My preferred web application stack is bottle + nginx + uwsgi + firebird + debian.

So this is my brief tutorial for this stack :

Install required packages :

apt-get update
apt-get install nginx nginx-extras python3 python3-pip python-virtualenv uwsgi uwsgi-plugin-python3

Prepare web files directory structure for nginx :

mkdir -p /var/www/bottledemo
chown -R www-data:www-data /var/www/bottledemo
chmod 755 /var/www

Let’s create our virtualenv for our applications. I prefer placing my virtaulenvs in opt directory :

mkdir /opt/venv
virtualenv /opt/venv/bottle -p python3

Time to activate our virtualenv and install bottle :

source /opt/venv/bottle/bin/activate
pip install bottle

To create our simple demo application :

nano /var/www/bottledemo/

And code of our simple demo application :<pre class=“lang:python> #!/usr/bin/env python from bottle import route, run, default_app @route(’/’) def index(): return “Hello from bottle with Python3 !” if \__name__ == “__main__”: run(host=“localhost”, port=8081) else: application = default_app() ```

Let’s check if everything is working so far :

python /var/www/bottledemo/

If your output is similar to below output then everything is well so far. When you locate to http://localhost:8081, your browser should say “hello” to you.

Bottle v0.12.4 server starting up (using WSGIRefServer())...
Listening on http://localhost:8081/
Hit Ctrl-C to quit.

Now we can safely deactivate our virtualenv,


and start nginx configuration, first we have to create a virtual host file for nginx :

nano /etc/nginx/sites-available/bottledemo

content of the nginx virtualhost is :

server {

        listen   80; ## listen for ipv4; this line is default and implied
        listen   [::]:80 default ipv6only=on; ## listen for ipv6

        root /var/www/bottledemo;

        access_log /var/log/nginx/bottledemo.access.log;
        error_log /var/log/nginx/bottledemo.error.log;

        location / {
                uwsgi_pass unix:/tmp/uwsgi.bottledemo.socket; #--&gt; This is referenced in uwsgi app ini file
                include uwsgi_params;


to activate our virtualhost we symlink it to sites-enabled directory :

ln -s /etc/nginx/sites-available/bottledemo /etc/nginx/sites-enabled/bottledemo

Now it is time to configure our uwsgi. First we create our uswgi appliaction configuration file :

nano /etc/uwsgi/apps-available/bottledemo.ini

bottledemo.ini content

plugins = python3
socket = /tmp/uwsgi.bottledemo.socket

virtualenv = /opt/venv/bottle
pythonpath = /var/www/bootledemo
chdir =  /var/www/bottledemo
file =

# like ngnix, uwsgi should be www-data.
uid = www-data
gid = www-data

and symlink to enabled applications :

ln -s /etc/uwsgi/apps-available/bottledemo.ini /etc/uwsgi/apps-enabled/bottledemo.ini

last touches :

/etc/init.d/nginx restart
/etc/init.d/uwsgi restart