Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#1736 closed enhancement (fixed)

[magic-removal] [patch] Add FastCGI support to manage.py

Reported by: jcrasta@… Owned by: adrian
Component: Core (Management commands) Version: magic-removal
Severity: normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Deploying a FastCGI django application is rather complicated, especially for first-time users, as there is at least one extra script needed to be deployed along with the application, along with installing the "flup" python package usually.

The attached patch (made for magic-removal, but it shouldn't be too hard to add this to trunk either) adds a "runfcgi" subcommand to manage.py and django-admin.py. Depending on your web-server configuration, running a fastCGI application might be as simple as:

$ ./manage.py runfcgi 

For more complicated setups, there might be something like this:

$ ./manage.py runfcgi method=prefork socket=/tmp/django.sock pidfile=/var/run/django-fcgi.pid

Through the versatality of flup, the FastCGI code can run over the "standard" fastCGI file-descriptor, or it can run over a TCP socket, or a unix domain socket (only available on POSIX systems).

I've included a help screen, and running 'runfcgi help' will print out the following:

runfcgi:
  Run this project as a fastcgi application. To do this, the
  flup package from http://www.saddi.com/software/flup/ is
  required.

Usage:
   django-admin.py runfcgi --setttings=yourproject.settings [fcgi settings]
   manage.py runfcgi [fcgi settings]

Optional Fcgi settings: (setting=value)
  host=HOSTNAME        hostname to listen on..
  port=PORTNUM         port to listen on.
  socket=FILE          UNIX socket to listen on.
  method=IMPL          prefork or threaded (default prefork)
  maxspare=NUMBER      max number of spare processes to keep running.
  minspare=NUMBER      min number of spare processes to prefork.
  maxchildren=NUMBER   hard limit number of processes in prefork mode.
  daemonize=BOOL       whether to detach from terminal.
  pidfile=FILE         write the spawned process-id to this file.
  workdir=DIRECTORY    change to this directory when daemonizing

Examples:
  Run a "standard" fastcgi process on a file-descriptor
  (for webservers which spawn your processes for you)
    $ manage.py runfcgi method=threaded

  Run a fastcgi server on a TCP host/port
    $ manage.py runfcgi method=prefork host=127.0.0.1 port=8025

  Run a fastcgi server on a UNIX domain socket (posix platforms only)
    $ manage.py runfcgi method=prefork socket=/tmp/fcgi.sock

  Run a fastCGI as a daemon and write the spawned PID in a file
    $ manage.py runfcgi socket=/tmp/fcgi.sock method=prefork \
        daemonize=true pidfile=/var/run/django-fcgi.pid

If any questions or clarifications are needed, one can reach me by my e-mail or as Crast on #django

  • James Crasta

Attachments (6)

django-management-fastcgi.diff (7.5 KB) - added by jcrasta@… 9 years ago.
FastCGI patch (use patch -pO in magic-removal )
fastcgi.txt (18.6 KB) - added by jcrasta@… 9 years ago.
ReST documentation of how to set up django with FastCGI
fastcgi.txt.diff (798 bytes) - added by mir@… 9 years ago.
small patch for fastcgi.txt
django-fastcgi-new.diff (8.3 KB) - added by jcrasta@… 9 years ago.
Updated django-management fastcgi patch as per suggestions, use patch -p0 in trunk
fastcgi-updated.txt (18.6 KB) - added by jcrasta@… 9 years ago.
Updated ReST documentation to go with updated patch, includes mir@…'s diff
django-fastcgi-new-fixed.diff (8.3 KB) - added by jcrasta@… 9 years ago.
fixed a spelling error, and added an import

Download all attachments as: .zip

Change History (14)

Changed 9 years ago by jcrasta@…

FastCGI patch (use patch -pO in magic-removal )

comment:1 Changed 9 years ago by Malcolm Tredinnick <malcolm@…>

This looks like the right idea to me. Would be a nice addition. A couple of comments on the implementation:

(1) When creating a daemon (on Unix-like systems), it is recommended to chdir('/') unless there is a good reason not to. The reasoning being that you could be starting from a filesystem that wants to be unmounted at some point in the future and having the current dir on that filesystem would prevent unmounting. So maybe the !homeDir parameter should default to '/'.

(2) Not too keen on just dropping this into management.py. I would prefer to see it in a separate module that can be invoked by management.py. The reason is that similar (but not identical) functionality will be useful for SCGI at some point and at some point, management.py starts to become huge and overwhelmed by a couple of server-side startup portions.

Otherwise, I like this. Nice work.

comment:2 Changed 9 years ago by jcrasta@…

Malcolm:

in response to 1:

chdir("/") is usually what many daemon processes do, in order to not use up
a handle on a directory thus causing
issues later on when someone wants to unmount a filesystem,
but it is common in django applications (that I have seen, anyway)
to use relative references to various things (sqlite db paths, template paths, static.file mapping paths)
especially in settings.py, and I think to assume a user always uses absolute paths is a bad move.

in response to 2:

I do agree with you on that point, but not being one of the django developers, I wasn't sure where to take liberty
to add my module. I can re-make my patch as a separate module and only insert the neccesary line into the
admin to import the module and such, but some direction as to where in the source tree would be helpful.
one thought was django.core.handlers, but it doesn't seem the right place as it's not
really a "handler" in itself, though it does use the wsgi handler. Or I can put it in django.utils
if that makes sense.

comment:3 Changed 9 years ago by adrian

This supercedes #152 and #1097.

Changed 9 years ago by jcrasta@…

ReST documentation of how to set up django with FastCGI

comment:4 Changed 9 years ago by mir@…

thanks for these fine docs!

In line 135 there should be an additional colon. I'll attach a patch.

Changed 9 years ago by mir@…

small patch for fastcgi.txt

comment:5 Changed 9 years ago by anonymous

  • Cc jcrasta@… added

Changed 9 years ago by jcrasta@…

Updated django-management fastcgi patch as per suggestions, use patch -p0 in trunk

Changed 9 years ago by jcrasta@…

Updated ReST documentation to go with updated patch, includes mir@…'s diff

comment:6 Changed 9 years ago by jcrasta@…

  • Cc jcrasta@… removed

As per malcomt and bitprophet's suggestions, I moved the bulk of the FastCGI addon out of management.py, and instead added a core/servers/fastcgi.py.

Also, the default directory to change to on daemonize will be "/" (which can be overridden with the workingdir= directive to runfcgi)

Finally, core/servers/fastcgi.py can be run standalone or the "runfastcgi" function can be imported and used from your own fastcgi shim script (though running it through manage.py gives you the advantage that you don't need to worry about setting DJANGO_SETTINGS_MODULE, but those who want to use the features of runfcgi in external scripts can do so. I updated the documentation to reflect this usage in a shim script.

Changed 9 years ago by jcrasta@…

fixed a spelling error, and added an import

comment:7 Changed 9 years ago by adrian

  • Status changed from new to assigned

comment:8 Changed 9 years ago by adrian

  • Resolution set to fixed
  • Status changed from assigned to closed

Added in [3174], and added first draft of docs in [3175].

Note: See TracTickets for help on using tickets.
Back to Top