Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Running Perl scripts from a single CGI-BIN, on a multiple-virtual hosting server

by ajt (Prior)
on Oct 02, 2001 at 17:48 UTC ( #116116=perlquestion: print w/replies, xml ) Need Help??

ajt has asked for the wisdom of the Perl Monks concerning the following question:

This question springs from a recent conversation I had with btrott and his rather excellent STAMP script.

Imagine if you will a typical Apache box, it's got one shared CGI-BIN, or mod_perl folder that is shared by all the various virtual domains on the box. Each domain looks different, so I want to make the script look different too.

QUESTION how do you neatly configure the script for all the various domains?

You can ask CGI to give you the virtual host name, and then check to see if there is a configuration file for it, if not you read a default one. This is what I tried, see code below. It works okay, but you'll end up with a folder full of config files, one per script per host, which may get messy.

So my question is, how do you neatly write CGI/mod_Perl script so that they can be shared on a mass-hosting Apache box, and yet maintain their own look'n'feel (via config), and what have you.

my $server = "localhost"; # Default host my $domain = ""; # Default domain my $conf_loc = "/someplace"; # Where config files live $server = $q->virtual_host() if $q->virtual_host(); # Where are +we? $server .= $domain unless ($server =~ /[$domain]$/i); # Need a do +main? if ($server =~ /^([-\w\.]+)$/) { # clean it $server = lc($1); chdir $conf_loc or error($q, qq(Unable to locate configuration fol +der $conf_loc)); $CFG_FILE = $server . ".$CFG_FILE" if ($server && -R "$server.$CFG +_FILE"); # If there is a specific file then use it }

$CFG_FILE is what STAMP expects to use, and error is it's error handling routine.

This is an addition to STAMP, I used for ilustration purposes. STAMP is cool, get it your self from it's author.

As ever thanks in advance.

Replies are listed 'Best First'.
Re: Running Perl scripts from a single CGI-BIN, on a multiple-virtual hosting server
by Masem (Monsignor) on Oct 02, 2001 at 18:05 UTC
    Assuming that the config files are not 'large' (eg Windows Registery-sized), would it not be better to have one .config for all the scripts, such that you have one config per virtual host? Obviously, you'd need to have XML or a similar layout on the config file, and new scripts should be able to add to the config file if they don't find defaults that they would expect.

    Dr. Michael K. Neylon - || "You've left the lens cap of your mind on again, Pinky" - The Brain
    It's not what you know, but knowing how to find it if you don't know that's important

      Masem I thought of that, I should have included it as an option (-- to me from my self).

      The problem with all in one file is that many scripts, STAMP included weren't designed for this, and you have to think with an extra level of nesting in the configuration stage. It's a good idea if you think about it first.

      However, imaging the situtuation where you're trying to replace Selena Sol or MSA scripts on a hosting companies server. Now you have the problem that each user has to edit the global file, which I don't think is smart, unless you build a process for editing such a file (really should be a DB I suppose on this scale), so that they can change their own bits.

      If you have multiple files, more sophisticated than my first stab, you can let users own and configure them on their own. Though now you have to be careful when you parse them....!

      My case is a bit simpler, it's just a bunch of web sites for the same company, but in differnt domains on the same box (.de etc), but I was wondering how you go about remplacing formmail et al on an under staffed hosting companies server.

      As ever thanks in advance

        Ok, here's another suggestion: make several levels of config files; one file at the global level, one per v.server at the server level, and possibly a third file local on the v.server's directory for local changes. The order that you'd search these is up to you; if none of the configuration settings are security related parameters, I'd first search user, then v.server, then global; otherwise, you could play around with flagging certain configuration variables that can only be set in the global or v.server files.

        This would allow changing one config parameters across a site at one file, while also allowing the end user some ability to configure their site as well.

        Dr. Michael K. Neylon - || "You've left the lens cap of your mind on again, Pinky" - The Brain
        It's not what you know, but knowing how to find it if you don't know that's important

Re: Running Perl scripts from a single CGI-BIN, on a multiple-virtual hosting server
by traveler (Parson) on Oct 02, 2001 at 18:20 UTC
    I agree with what Masem said, but I'd create one config file per virtual domain or virtual host. That way if you move one domain to another host, it is easy to move its config file rather than editing a big one. I agree that XML is the way to go, both for readability and for maintainability. Something like the following might be a start:
    <config vhost="my.virtual.hostname"> <script name=""> <logfile name="/wherever/some_log" /> etc </script> <script name=""> etc </script> </config>
    Check CPAN for some modules that help you parse XML. I especially like XML::Simple for config files.
    HTH, --traveler
Re: Running Perl scripts from a single CGI-BIN, on a multiple-virtual hosting server
by pixel (Scribe) on Oct 02, 2001 at 19:54 UTC

    If you are going to have separate files for each of the servers, then why not store them within each virtual server's document space? That way the CGI script could contain a line like:

    require "$ENV{DOCUMENT_ROOT}/";

    and would pick up a different file when run from each server.

    Blessed Be
    The Pixel

Re: Running Perl scripts from a single CGI-BIN, on a multiple-virtual hosting server
by mikeB (Friar) on Oct 02, 2001 at 19:54 UTC
    I do something similar. It's currently implemented with IIS/SqlServer, but should work in *nix land as well.

    The scripts use the name of the virtual host as an index to a database table which specifies per-site options, including style sheet names, logo graphics, etc. This, combined with the use of HTML::Template, allows customization of look-and-feel, as well as a few functional differences in the various sites, while maintaining a single codebase.

    Of course, you have to have a database available...

Re: Running Perl scripts from a single CGI-BIN, on a multiple-virtual hosting server
by perrin (Chancellor) on Oct 02, 2001 at 18:54 UTC
    Well, now I'm confused. You seemed to be asking how to avoid having a separate config file for each virtual host. Masem suggested a way to do that and you replied that you don't want to share it for security reasons, which means you have to have separate config files. So what are you trying to do?
      Sorry for the confustion...

      I think I may have muddied my own waters here. I don't want to configure every script on a server for every user, all in one go. Well I could but that's another question...

      I can do it with one file per script, that's how STAMP et al do it now. The problem is, that it's not designed for multiple users, so it wont scale properly. Lots of other scripts are designed the same way, in fact until I started to think about multiple domains on the same box, all of mine were built this way.

      Using multiple files allows individual users to to control their own space. Problem is that it seems messy. You get files all over the place, but you know that user X can't touch user Y's settings.

      Imagine three domains, A, B and C each which usess three scripts, and Unless I write all three scripts, each script will have it's own legacy configuration system, which may need changing, so that each script does differnet things per different virtual-server.

      I started with STAMP as it's a decent formmail replacement, now if I want to configure it differently for each domain, I have to either force it's configuration system, or create a file per virtual-server - which was my own initial solution.

      My approach is to use one file that the script will default to if nothing else is found, and one file per virtual-host that it tries first. This will be duplicated per script.

      Next I try another script, and this uses it's own different configuration system, which again may need changes to make it multi-host aware. Now things are starting to get scary....

      Doing it this way I'll end up with one config file per script per virtual host plus a default per script, 12 in the example above.

      Is there a better way of doiong this? Given that some of the scripts will be new and some will be legacy? What is the best way of tackling the problem.

      • I like the one file approach, (not nessisarily for every script), but I'd have to write a way of controling it, as it's unsafe as it stands.
      • The multiple config files is simpler, and works with largacy code better, but could get messy.

      Much thanks for the suggestions so far, I do appreciate input, it's very helpful. If I have still confused anyone I can take this off line if you prefer.

        Let's boil down your requirements:
        • For every script, be able to vary its configuration for each virtual host.
        • Manage as few files as possible.
        • Prevent users of different virtual hosts from changing each other's files.
        With that set of requirements, you seem to have the best solution: a default config for each script, with the ability to override it for each virtual host. The only thing I could add is that you may want to make the overriding more fine-grained. You could do this by converting the scripts to use a config system that supports option overriding, like AppConfig, or you could generate the config files from simpler templates, so that the user managing a particular virtual host just fills out a form or something and your program generates the approriate script-specific configs.
Re: Running Perl scripts from a single CGI-BIN, on a multiple-virtual hosting server
by Caillte (Friar) on Oct 02, 2001 at 18:56 UTC

    When we did something similar to what (I think) you are trying to do, we did it in the following way:

    • Use a seperate Apache.conf file for each site.
    • Define a variable of the same name in each .conf file
    • Knock up a file that checks the define and sets default colours etc depending on the site referred to
    • Start each CGI file with a do(; line
    • Refer to these default variables.
    With this setup we got three functionally similar sites running off the same cgi-bin directory, which is what I think you are looking to do.

    $japh->{'Caillte'} = $me;

Re: Running Perl scripts from a single CGI-BIN, on a multiple-virtual hosting server
by c (Hermit) on Oct 02, 2001 at 19:41 UTC
    I've found myself in a very similar situation to your own, and headed down the same path. In the end, I decided that coming up with a global configuration file that each globally accessible script could pull from was just not the solution I was looking for. After all, some scripts just needed a small bit of tweaking to make them usable by all virtual hosts on my machine. Instead, I took the approach of tweaking each script such that it would be globally usable without further editing by end users, and hopefully in a manner that would allow the script to avoid further editing as new domains were placed on the machine.

    My small case in point is something that I think you referred to in your post, a formmail script.

    The script relies on checks against the $ENV{'HTTP_REFERER'} variable and provides an array that can hold the various domains on your machine. To make the script globally accessible without having to update it per domain, I rewrote the array to pull all local domains from already existing file like /etc/mail/ or perhaps your zone files from dns.

    Regardless of how you do it, chances are that each script just needs a small rewrite to bring it up to speed as globally accessible. I am far from being a monk with major perl-fu power, but it certainly fit my needs and took very little time to do.

    my @referers; open(FH, "/etc/mail/") or die "Cant open $i! : $!\n"; while(<FH>) { chomp; my $www = "www.$_"; push(@referers, $_); push(@referers, $www); } close(FH); }

    humbly -c

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2022-05-29 00:22 GMT
Find Nodes?
    Voting Booth?
    Do you prefer to work remotely?

    Results (101 votes). Check out past polls.