Nginx and python

Posted on Sunday, February 2, 2014


In this guide I am going to go over install nginx and getting it to work with python




Install uwsgi


A good place I got some notes from


> sudo apt-get update
> sudo apt-get install uwsgi
> sudo apt-get install uwsgi-plugin-python



Now for a test, create a directory to put a test python file


> cd
> mkdir py-test
> cd py-test
> vi test.py


And put the following in it (this code is from http://perlmaven.com/deploying-pyton-with-uwsgi-on-ubuntu-13-10 )


def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return "Hello World From Python"

Then run it via uwsgi


> uwsgi --http-socket :9090 --plugin python --wsgi-file test.py

Open up the url.  In my case its http://192.168.0.186:9090/

 


It worked

Now stop the running program by hitting ctrl+c




Install nginx


Run the following commands


> sudo apt-get install nginx




Update nginx


I am going to place my website in a directory I am going to make /www  I also made a /www/logs folder to put site logs in


> sudo mkdir -p /www/main-site
> sudo mkdir -p /www/logs


Create a simple index.html file there for testing


> sudo vi /www/main-site/index.html


Put the following in the file


<html>
<body>
<h1>Test</h1>
</body>
</html>

And open http://192.168.0.186/  (in my case it is running on 192.168.0.186… change this to match your server ip)




Now update /etc/nginx/nginx.conf


> sudo vi /etc/nginx/nginx.conf



Edit the document to the following  (my server happens to be running on ip address 192.168.0.186)


user www-data;
worker_processes 4;
pid /var/run/nginx.pid;

error_log /var/log/nginx/error.log;

events {
  worker_connections 1024;
  use epoll;
  multi_accept on;
}

http {

  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  server {
    listen       80;
    keepalive_timeout    70;

    server_name  192.168.0.186;
    #Logs
    access_log /www/logs/main-site-access.log;
    error_log /www/logs/main-site-error.log;

    # doc root
    root /www/main-site;
    location ~ \.py$ {
      uwsgi_pass   127.0.0.1:9000;

      uwsgi_param  QUERY_STRING       $query_string;
      uwsgi_param  REQUEST_METHOD     $request_method;
      uwsgi_param  CONTENT_TYPE       $content_type;
      uwsgi_param  CONTENT_LENGTH     $content_length;

      uwsgi_param  REQUEST_URI        $request_uri;
      uwsgi_param  PATH_INFO          $document_uri;
      uwsgi_param  DOCUMENT_ROOT      $document_root;
      uwsgi_param  SERVER_PROTOCOL    $server_protocol;
      uwsgi_param  HTTPS              $https if_not_empty;

      uwsgi_param  REMOTE_ADDR        $remote_addr;
      uwsgi_param  REMOTE_PORT        $remote_port;
      uwsgi_param  SERVER_PORT        $server_port;
      uwsgi_param  SERVER_NAME        $server_name;


      include uwsgi_params;
    }
  }
}


This will feed all files that end in ".py" to 127.0.0.1:9000

Restart nginx


> sudo /etc/init.d/nginx restart



Uwsgi and ini file


I had a few issues trying to even get this to work a little I did get some information on an issue I was having at http://stackoverflow.com/questions/18501373/flask-nginx-uwsgi-python-application-not-found [4]

It helped me get past this error.

uWSGI Error
Python application not found


Create a uwsgi ini file.


> cd
> vi uwsgi.ini


And place the following in it


[uwsgi]
chdir = /www/main-site
socket = 127.0.0.1:9000
master = true
workers = 4
plugin = python
pp = /www/main-site
module = test




Create the python program


> cd /www/main-site/
> vi test.py


And put the following in it (this code is from http://perlmaven.com/deploying-pyton-with-uwsgi-on-ubuntu-13-10 )


def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return "Hello World From Python"


Now run the uwsgi by hand


> cd
> sudo uwsgi --ini uwsgi.ini








Success !! kinda….


This set up is enough to do a test I currently need to do but it is not complete at all



One of the key problems I have is with the ini file


[uwsgi]
chdir = /www/main-site
socket = 127.0.0.1:9000
master = true
workers = 4
plugin = python
pp = /www/main-site
module = test



They pp is the python path and the module is the actual program
So pp = /www/main-site and module = test

Together it says to run /www/main-site/test.py

I set up nginx to forward all *.py files to the uwsgi server running on port 9000.  Then the uwsgi only opens /www/main-site/test.py


As an example f I open the url http://192.168.0.186/test/wrong/bob.py
I get the same site









Get it working with different .py files


I found a way to get it working using the suggestions at

Warning!!

THIS IS NOT A GOOD WAY TO RUN A SERVER, but it works.  THIS IS NOT SOMETHING TO PUT INTO A REAL ENVIRONMENT.


Edit nginx.conf


> sudo vi /etc/nginx/nginx.conf



Edit the document to the following  (my server happens to be running on ip address 192.168.0.186)


user www-data;
worker_processes 4;
pid /var/run/nginx.pid;

error_log /var/log/nginx/error.log;

events {
  worker_connections 1024;
  use epoll;
  multi_accept on;
}

http {

  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  server {
    listen       80;
    keepalive_timeout    70;

    server_name  192.168.0.186;
    #Logs
    access_log /www/logs/main-site-access.log;
    error_log /www/logs/main-site-error.log;

    # doc root
    root /www/main-site;
    location ~ \.py$ {
                include uwsgi_params;
                uwsgi_param UWSGI_FILE $request_filename;
                uwsgi_param UWSGI_TOUCH_RELOAD $request_filename;
                uwsgi_param SCRIPT_NAME $uri;
                if (-f $request_filename) {
                        uwsgi_pass 127.0.0.1:9000;
                }
    }
  }
}



Restart nginx


> sudo /etc/init.d/nginx restart




Run uwsgi from the command with the following command


> sudo uwsgi -s :9000 -M -i --processes 4 --threads 2 --plugins python





You get







Create a second python program


Now to test it make another python program in a subdirectory


> sudo mkdir -p /www/main-site/sub-dir/test
> sudo vi /www/main-site/sub-dir/test/test-2.py


Put the following in the program


def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return "This is a test from the second python program"



And you should see



That works J  I apologize that it is not a solution for a live environment but maybe it will help someone.

If anyone has a better way to do this or knows a more complete way please feel free to comment.


References
[1]  Deploying Python with uWSGI and Nginx on Ubuntu 13.10
       Visited 2/2014
[2]  Setting up Django and your web server with uWSGI and nginx
      Visited 2/2014
[3]  DEPLOYMENT WITH UWSGI AND NGINX
       Zachary Voase
       Visited 2/2014
[4]  uwsgi and wsgi-based python apps in a shared hosting environment
        Roberto De Ioris
       Visited 2/2014


1 comment:

  1. This is a very nice one and gives in-depth information. I am really happy with the quality and presentation of the article. I’d really like to appreciate the efforts you get with writing this post. Thanks for sharing.
    Full stack Classes in Bangalore

    ReplyDelete