Bottle, uwsgi and nginx are all pretty tools, which are popular for fast deployment. I love using Bottle for small apps due to its simplicity and usability (See also how to use Bottle on GAE). 

Bottle even makes you unaware of writting a web application.  

In this post, I will walk you through how to run Bottle app with uwsgi and nginx step by step. I will also show some pitfalls you might encounter. 

Step 1.  install everything needed: 


sudo apt-get install uwsgi uwsgi-plugin-python python-bottle nginx

As you can see, I am assuming you're using ubuntu/debian.

Step 2.  creat a project named 'bottlebasis' with following files/folds: 


step 3:  coding with, which pretty much does the main job. See a simple example


bottle with uwsgi and nginx

import bottle
from bottle import template
import os

app = application = bottle.Bottle()
#bottle.TEMPLATE_PATH.insert(0, os.path.dirname(os.path.abspath(__file__)) +"/views")
#bottle.TEMPLATE_PATH.insert(0, os.path.dirname(os.path.abspath(__file__)))
#bottle.TEMPLATE_PATH.insert(0, '/data/Dropbox/python/web/bottlebasis/views')

def static(filename):
	Serve static files
		return bottle.static_file(filename, root='{}/static'.format(os.path.dirname(__file__)))
		return '{}/static'.format(os.path.dirname(os.path.abspath(__file__)))

def show_index():
	serve "index" page
	return 'Hello, this is the index page'

def show_page(name):
	show how to use a simple template for rendering.
	#return str(bottle.TEMPLATE_PATH) ##+ 
		return template('page', url_name=name)
	except Exception, e:
		return "<p>Error: %s</p> <p>%s</p>" % (str(e), os.getcwd())

if __name__ == '__main__':, host='', port=8080) ##host='', which makes visitable outside.

In order to quickly test your code, you can simple run 'python'.

And then you should be able to see something expected at http://localhost:8080. 

Step 4: using uwsgi

create a file '/etc/uwsgi/apps-available/bottlebasis.ini' as follows:



#master-as-root = true
socket = /run/uwsgi/app/bottlebasis/socket
chdir = /data/Dropbox/python/web/bottlebasis
master = true
plugins = python
file =
uid = www-data
gid = www-data
chmod-socket = 664
chown-socket = www-data:www-data

chdir is your project directory. 

After that ln -s /etc/uwsgi/apps-available/bottlebasis.ini /etc/uwsgi/apps-enabled/bottlebasis.ini

Start the service


sudo service uwsig start

Step 5: start nginx

edit file "/etc/nginx/conf.d/bottle.conf"


upstream _bottle {
    server unix:/run/uwsgi/app/bottlebasis/socket;

server {
    listen [::]:80;
    listen 80;
    root /data/Dropbox/python/web/bottlebasis;

    location / {
        try_files $uri @uwsgi;

    location @uwsgi {
        include uwsgi_params;
        uwsgi_pass _bottle;

Then start the nginx serve: 

sudo service nginx start


1) chdir(): Permission denied [core/uwsgi.c line 2468]

2) 2014/04/14 11:32:35 [crit] 32295#0: *1 stat() "/data/Dropbox/python/web/bottlebasis/static/food.jpg" failed (13: Permission denied), client:, server:, request: "GET /static/food.jpg HTTP/1.1", host: "" 

    chmod -R +x /data/Dropbox/python/web/bottlebasis/

if there is something with nginx, you can use 'sudo nginx -t' to test the configuration file. 



The source code can be download from:














Tags: bottle

Posted in python |

Leave a Reply