Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re: Change cgi script to PSGI app

by tobyink (Canon)
on Sep 11, 2014 at 09:00 UTC ( #1100273=note: print w/replies, xml ) Need Help??

in reply to Change cgi script to PSGI app

You have several deployment solutions, but they all boil down to an initial choice between two main options:

  1. You can serve the app through Apache, so it appears to be just one more "page" on your current web server; or

  2. You can serve the app through a stand-alone server, in which case it will be running on a different port (or even on a different host if you liked). Optionally, Apache can be configured to use mod_rewrite/mod_proxy to make the app appear like you've used choice #1 above.

If you want to serve your app through Apache, mod_perl is usually a fairly simple way to set it up, and a reasonably efficient way to run it, but you've already ruled that out. You can accomplish something similar using FastCGI, though I've always found that trickier to set up.

The final Apache-based way is to deploy a PSGI script as CGI. Just rename your .psgi file to .cgi, mark it as executable (chmod +x), and make sure it includes this shebang line:

#!/usr/bin/env plackup

Now it's just a regular CGI script, albeit one that uses Plack a lot internally. See Plack::Handler::CGI for details. This is a really easy deployment option, which works just about anywhere. However, because your whole PSGI app needs to be loaded for each request, it's not an especially efficient solution. (For simple apps that don't load a bajillion modules, it's often perfectly acceptable.)

Using a stand-alone server though is generally the most popular option. There are various PSGI servers on CPAN, including Starman and HTTP::Server::PSGI (which comes bundled with Plack). They each have different performance profiles. Generally speaking, you trade CPU for memory. The faster ones take up more memory. The smaller ones are slower. Test out a few, and see which one performs best for your app.

As you have noted, you'll want to run this as a background process, and probably do things like monitor it, to check that it doesn't crash (and automatically restart it if it does crash), and have it auto-restart after a hardware reboot, and so on.

For this I strongly recommend using Ubic to create /etc/rcX.d/-style services. In particular, you'll want the Ubic::Service::Plack plugin (or if you deploy via Starman, Ubic::Service::Starman is another option).

For my personal site, I use an interesting blend of Perl solutions. Most of the site are static HTML pages, generated from Atom by a Perl script, and served though Apache. The e-mail contact form is a PSGI app deployed via CGI. My SPARQL endpoint is another PSGI app running on a stand-alone HTTP::Server::PSGI server, using Ubic to keep it running, and with some custom Ubic plugins to monitor its memory usage, and restart it if the process gets too big. Over-engineering much?

Anyway, I'll stop rambling, but I hope this has been of some help.

TL;DR: use Ubic

Replies are listed 'Best First'.
Re^2: Change cgi script to PSGI app
by mohan2monks (Beadle) on Sep 11, 2014 at 09:13 UTC
    Yes it is been of much help.
    Thank you very much it should take me somewhere though i am still away from putting it to production.
Re^2: Change cgi script to PSGI app
by sundialsvc4 (Abbot) on Sep 12, 2014 at 01:12 UTC

    Toby, just keep writing more of those “ramblings” of yours, anytime!   But I do find myself with a couple of questions / points for clarification, if you would, please.

    Ordinarily, I do use PSGI, by means of Plack.   (N-O-T to ignite any religious wars here, I do not use mod_perl.)   If everything is going to be done on a single computer, I simply let Apache own the child processes, e.g. using mod_fastcgi.   My only use for plackup is as a command-line tool which allows me to run the scripts and connect to them on localhost for development purposes only; it is never put into any “shebang” lines.   Therefore, I am quite puzzled by your other suggested use for it.   I don’t quite understand you on that point ...

    Although I have never had need to use Plack’s adapter for CGI-scripts, its docs seem sensible.   Quite frankly, I just design apps to run under Plack.

      "Therefore, I am quite puzzled by your other suggested use for it. I don’t quite understand you on that point"

      The use of plackup in a shebang line for CGI scripts is documented in Plack::Handler::CGI. If you're interested in how/why it works, read on.

      plackup's normal behaviour is to run a server which listens on a TCP port, and handles multiple HTTP requests, and keeps going until it gets killed. You can observe this behaviour by running:

      plackup -e'sub { [200,[],[q/ok/]] }'

      It will print out a URL; you can paste that into your browser, and it will serve up a small text file containing the word "ok". And you can hit "reload" and it will do it again and again. Awesome. But, of course, not what you want from a CGI script! So how is plackup any good in a shebang line?

      Hit Ctrl+C to kill plackup, and then set the following environment variables:


      Now run this again:

      plackup -e'sub { [200,[],[q/ok/]] }'

      And you'll see that instead of spawning an HTTP server and printing out its address for you, plackup now behaves like a CGI script, printing out the response headers and body to STDOUT.

      plackup (or rather the guess sub defined in Plack::Loader) detects that it's running in a CGI environment and behaves appropriately.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1100273]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (1)
As of 2023-06-02 02:43 GMT
Find Nodes?
    Voting Booth?

    No recent polls found