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


No comments:

Post a Comment