Running CGI Scripts Under Catalyst

It is possible to run most CGI scripts under Catalyst using the modules Catalyst::Controller::WrapCGI and Catalyst::Controller::CGIBin.

Why would you want to do this?

Assuming you have a legacy CGI application, you may want to:

  • integrate and package a CGI script into your Catalyst application, so you can (for example) use the Catalyst Authentication framework.
  • have a Perl CGI script compiled on startup and cached, as with ModPerl::Registry, but in a FastCGI environment rather than with mod_perl under Apache.

port a simple mod_perl application to Catalyst.

An Example

Let's get the wwwboard application from the NMS project ( running under Catalyst.

We'll call the Catalyst application WWWBoard.

First, make a root/cgi-bin directory in your app, then copy the file there.

Put the files wwwboard.html and faq.html into root/static.

Edit the configuration block in to:

    $basedir =  WWWBoard->path_to('root/static');
    $baseurl = 'http://localhost:3000/';
    $cgi_url = 'http://localhost:3000/cgi-bin/';

Next, make a Controller for running your CGIs:

    package WWWBoard::Controller::Board;

    use strict;
    use warnings;
    use parent 'Catalyst::Controller::CGIBin';


Tell Static::Simple to not ignore .html files in

        name => 'WWWBoard',
        static => {
            ignore_extensions => [ 'tt' ],

Rewire some URLs to the files the CGI will generate in Controller/

    __PACKAGE__->config->{namespace} = '';

    sub index : Path Args(0) {
        my ($self, $c) = @_;


    sub board_html : Path('wwwboard.html') Args(0) {
        my ($self, $c) = @_;


    sub faq_html : Path('faq.html') Args(0) {
        my ($self, $c) = @_;


    sub messages :Local Args {
        my ($self, $c, @args) = @_;

        $c->serve_static_file($c->path_to('/root/static/messages', @args));

Start the server, and you will be taken to a functional message board.

Even non-Perl CGIs will work, but of course these will not be pre-compiled.

Porting mod_perl Apps

The CGI environment is a bit closer to mod_perl than the regular Catalyst Controller environment, e.g. you can print to STDOUT.

The first step would be to rewrite your handler sub to take $c instead of $r as a parameter, and replace the Apache request methods with the equivalent Catalyst framework methods.

Replacing things like Apache::Session with Catalyst::Plugin::Session is also fairly trivial.

Then your URL handler would look like:

    use parent 'Catalyst::Controller::WrapCGI';
    require My::ModPerl::Handler;

    sub my_handler : Local {
        my ($self, $c, @args) = @_;

        $self->cgi_to_response($c, sub {

Other Examples

Justin Hunter (arcanez) has gotten the Movable Type blogging software running under Catalyst. It is available here:

Hans Dieter Pearcey (confound) has gotten the Bugzilla bug-tracking project running under Catalyst. It is available here:


Caelum: Rafael Kitover <>