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 :
1 2 |
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 :
1 2 3 |
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 :
1 2 |
mkdir /opt/venv virtualenv /opt/venv/bottle -p python3 |
Time to activate our virtualenv and install bottle :
1 2 |
source /opt/venv/bottle/bin/activate pip install bottle |
To create our simple demo application :
1 |
nano /var/www/bottledemo/myapp.py |
And code of our simple demo application :
1 2 3 4 5 6 7 8 9 10 |
#!/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 :
1 |
python /var/www/bottledemo/myapp.py |
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.
1 2 3 |
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,
1 |
deactivate |
and start nginx configuration, first we have to create a virtual host file for nginx :
1 |
nano /etc/nginx/sites-available/bottledemo |
content of the nginx virtualhost is :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
server { server_name bottledemo.mydomain.com; ## -> DO NOT FORGET TO CHANGE THIS LINE ACCORDING TO YOUR DOMAIN 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; #--> This is referenced in uwsgi app ini file include uwsgi_params; } } |
to activate our virtualhost we symlink it to sites-enabled directory :
1 |
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 :
1 |
nano /etc/uwsgi/apps-available/bottledemo.ini |
bottledemo.ini content
1 2 3 4 5 6 7 8 9 10 11 12 |
[uwsgi] plugins = python3 socket = /tmp/uwsgi.bottledemo.socket virtualenv = /opt/venv/bottle pythonpath = /var/www/bootledemo chdir = /var/www/bottledemo file = myapp.py # like ngnix, uwsgi should be www-data. uid = www-data gid = www-data |
and symlink to enabled applications :
1 |
ln -s /etc/uwsgi/apps-available/bottledemo.ini /etc/uwsgi/apps-enabled/bottledemo.ini |
last touches :
1 2 |
/etc/init.d/nginx restart /etc/init.d/uwsgi restart |
Only suggestion I would make, is not to put your uwsgi socket in /tmp, use /run instead.
nginx fails to reload when I restart it, or stop start it. I have brand new ubuntu 14.04 and exactly fallowed your steps.
My app did not start as local host i had to enter it’s internal IP does it have anything to do with it?
About nginx problem: What is in the logs? Also you can try
service nginx restart
for ubuntu. Please check : http://askubuntu.com/questions/19320/how-to-enable-or-disable-servicesAbout binding address : It depends on your nginx configuration. Did your nginx really listen to the localhost adddress?
Seems like I left “default” word in my second file that I made under /etc/nginx/sites-available, that’s why nginx was thinking that it has two default sites.
Once I removed that, all semed to work. Thanks for the great tutorial, it’s in my bookmarks now!