2

I've already looked at other threads on this, but most don't go into enough setup detail which is where I need help.

I have an Ubuntu based VPS running with nginx, serving PHP sites through php-cgi on port 9000.

I'd like to start doing more with Python, so I've written a deployment script which I essentially want to use as a post-receive hook on my local GitLab server as my first python script. I can run this script successfully by running python script.py on the command line but in order to use this as a post-receive hook I need it be able to access it via http.

I looked at this guide on the nginx wiki but partway down is says to:

And start the django fastcgi process:

python ./manage.py runfcgi host=127.0.0.1 port=8080

Now, like I said I am pretty new to python, and I have never used the Django framework. Can anyone assit on how I am supposed to start the fastcgi server? Do I replace ./manage.py with the name of my script? Any help would be appriciated as everything I've found online refers to working with Django.

Community
  • 1
  • 1
Daniel Groves
  • 472
  • 2
  • 8
  • 21
  • @Vitaliy How can that *possibly* be relevant if the question is how to expose this code over HTTP? – millimoose Apr 05 '13 at 18:06
  • @Vitaliy I don't understand how that is relevant? It doesn't even use a database anyway. – Daniel Groves Apr 05 '13 at 18:08
  • you should read the articles linked to in the answer to http://stackoverflow.com/questions/11216658/what-is-the-disadvantage-of-using-djangos-fastcgi-server ; tldr- cgi isn't really recommended for Python development, WSGI is the modern protocol. – Jonathan Vanasco Apr 05 '13 at 18:26
  • @JonathanVanasco Isn't WSGI mostly used as an abstract interface between an appserver like *paster* and *gunicorn* in a setup where you have Apache/nginx reverse-proxy to a bunch of worker processes? Direct support for it in "real" webservers isn't really a thing. If the OP already has a nginx server that he knows has FastCGI enabled and configured, there's nothing really wrong with going with it. (It doesn't seem like the WSGI module is standard in nginx, so it might not be available in their build, and [the documentation for it](http://wiki.nginx.org/NgxWSGIModule) looks scary.) – millimoose Apr 05 '13 at 18:31
  • WSGI is used as an abstract interface like that, but it also drives the design principles of things like Flask , Paste, web.py etc. nginx ships with wsgi support through the uwsgi server. there's nothing wrong with staying in CGI - it's just an old & outdated method for web scripting. if you're learning how to use python for web stuff, it makes more sense to learn the current technology than old stuff that people don't really use. plus you get the benefits of middleware, local test servers (through whatever framework), and don't have to use the cgi module. – Jonathan Vanasco Apr 05 '13 at 19:32
  • if one were to stay in FCGI -- running a fcgi server for both PHP and Python can be a headache, especially on a virtual server that will have resource limitations. you'd want to have multiple fcgi configurations running - so that PHP and Python loads are prioritized and optimized differently. – Jonathan Vanasco Apr 05 '13 at 19:37
  • @JonathanVanasco I was going off the assumption that **1)** getting *CGI* to run is easier than setting up a proxy, supervisor, and a worker; **2)** the OP just wants to get the job done instead of learning how to do things "right" when there's no *tangible* benefits to be gained in his situation; **3)** the OP isn't really doing "web stuff" in Python, they're just coding a post-receive hook for an internal Git repo, which doesn't sound like it needs to be highly scalable or reliable or anything. In that case, "do the easiest thing that will work" is the way to go. – millimoose Apr 05 '13 at 22:17
  • @JonathanVanasco Now, of course, it turned out I was wrong about assumption **1)** which makes the distinction completely moot, and I admitted as much and covered the issue in my answer by now. If you have to do proxy+supervisor+worker *anyway*, it doesn't matter what the worker is based on. My whole aim was to avoid having to configure an additional piece of software (the supervisor) to make things simpler, as befits the use case. With *nginx* that's not an option, so, meh. Now if, in fact, the OP does want to do high-load Python sites, they should definitely look into *uWSGI* / *gunicorn*. – millimoose Apr 05 '13 at 22:22

1 Answers1

3

Do I replace ./manage.py with the name of my script?

No. It's highly unlikely your script is a FastCGI server, or that it can accept HTTP requests of any kind since you mention running it over the command line. (From what little I know of FastCGI, an app supporting it has to be able to handle a stream of requests coming in over stdin in a specific format, so there's definitely some plumbing involved.)

I'd say the easiest approach would be to use some web framework just to act as HTTP/FastCGI middleware. For your use a "microframework" like Flask (or even Paste but I found the documentation inscrutable) sounds like it'd work fine. The idea would be to have two interfaces to your main code, one that can handle command line arguments, and one that can handle a HTTP request, ultimately both would just call one function that actually does the work. (If you want to keep the command-line version of the app.)

The Flask documentation also mentions using uWSGI or standalone workers as deployment options. I'm not familiar with the former; the latter I wouldn't recommend for a simple, low-traffic app for the same reasons as the approach in the next paragraph.

Considering you use a VPS, you might even be able to just run the app as a standalone server process using the http.server module, but I'm not sure that's the better choice unless you absolutely want to avoid using any sort of framework. You'd have to make sure the app starts up if the server is rebooted or that it restarts when it crashes and it seems easier to just have nginx do the job of the supervisor.

UPDATE: Scratch that, it seems that nginx won't handle supervising a FastCGI worker process for you, which would've been the main advantage of the approach. In light of that it doesn't matter which of the three approaches you use since you'll have to set up a service supervisor one way or the other. I'd say go with uWSGI since flup (which is needed for Flask+FastCGI) seems abandoned since 2011, and the uWSGI protocol is apparently supported in nginx natively. Otherwise you'd need to use a different webserver than nginx, one that will manage a FastCGI worker for you. If this is an option, I'd consider Cherokee, which can be configured using a web GUI.

tl;dr: you need to write a (very simple) webapp. While it is feasible to do this without a web framework of any kind, in my opinion using one is easier, since you some (nontrivial) plumbing for free and there's a lot of guidance available on how to deploy them.

millimoose
  • 39,073
  • 9
  • 82
  • 134
  • 1
    http://webpy.org is an even smaller framework ; to reiterate my comment to the question: when it comes to Python web development, CGI is deprecated and WSGI is the current recommended approach. – Jonathan Vanasco Apr 05 '13 at 18:29
  • @JonathanVanasco It'd be even better if you could provide an answer on how to wire up nginx with a WSGI app. I seriously doubt it's just a drop-in replacement, seeing as WSGI requires either switching to a proxy+workers architecture, or adding a third-party module to nginx. I'd argue that FastCGI is perfectly fine for an app of the OP's scope, and that the benefits of proxy+workers don't apply here. You're essentially sending the OP to do some yak-shaving just for the sake of avoiding CGI. – millimoose Apr 05 '13 at 18:39
  • @JonathanVanasco And for what it's worth, I don't see how FastCGI and WSGI are mutually exclusive technologies. FastCGI is an "on-the-wire" protocol that allows a "worker" Python process to be reused for multiple HTTP requests. WSGI is an abstract way of representing those HTTP requests on the Python side. If I understand the docs I linked to correctly, all `flup` does is that it parses FCGI requests and converts them to WSGI calls that any Python framework will understand. So the choice isn't FCGI vs. WSGI, it's FCGI vs. standalone HTTP workers vs. embedding Python in the front server. – millimoose Apr 05 '13 at 18:46
  • @JonathanVanasco In fact, the SO question you linked to says the very same thing. And links to a bunch of other questions that *also* say comparing the two is meaningless. They serve entirely different purposes in the architecture. – millimoose Apr 05 '13 at 18:49
  • Just what I was after, thanks everyone. I'll look at getting uWSGI installed now, I only started with Fast CGI as thats what I was using for PHP. I'm always up fro better solutions if their are any available. – Daniel Groves Apr 05 '13 at 19:29