Multilingual PSGI-web deployment

2019-03-27 16:32发布

问题:

I plan develop one web application with PSGI/Plack. (probaly with Dancer, but not decided yet).

The applicatiion should be utf8, multilingual (with Locale::Maketext) and (ofc) will contain some statical pages in the given language. My idea is deploy it in different language domains like en.example.com, de.example.com etc. The application itself is simple, mostly will only fill templates with localized texts and some other (light) functionality.

What is the best solution to deploying one application for mutiple language-based sub-domains in one physical machine?

My current research ended with this solution: need to use Apache and its name based virtual servers for every language subdomain.

<VirtualHost en.example.com>
    ServerName en.example.com
    DocumentRoot /path/to/site/en/files
    <Location />
        SetHandler perl-script
        PerlResponseHandler Plack::Handler::Apache2
        PerlSetVar psgi_app /path/to/site/en/en.psgi
    </Location>
</VirtualHost>

Questions:

  • What is the best solution?
  • Exists any solution with Starman or other pure-perl server? If yes, how? Reverse proxy?
  • Will be the pure perl solution better (faster)?
  • should i consider some other solution? (fcgi, nginx etc...)

Any other ideas/things what can have impact to development itself?

回答1:

Use Plack::App::URLMap to setup a virtualhost in Starman (or whatever PSGI compatible web servers):

use Plack::App::URLMap;
my $en_app = generate_app('en');
my $ru_app = generate_app('ru');

my $app = Plack::App::URLMap->new;
$app->map("http://en.example.com/" => $en_app);
$app->map("http://ru.example.com/" => $ru_app);
$app->to_app;

in generate_app you can setup/configure whatever needed to return a new PSGI app. If you want to share the same $app instance but want to dynamically change the behavior, you can do so by writing PSGI middleware, like:

my $app = sub { MyApp->run(@_) };
my $en_app = sub {
   my $env = shift;
   $env->{'myapp.language'} = 'en';
   $app->($env);
};
my $ru_app = sub { ... }; # same

Note that you probably want to put Starman behind proxy, in which case you should configure the frontend (nginx/Apache/lighttpd etc.) to forward the Host: header as it is to the backend.



回答2:

I didn't think there is a "best" way, just many different ways and every one have pros/cons.

Setting up Apache like you did is possible and i don't see why this should be a bad way. Another way is to "mount" every application to path. This is further described here: http://suryahunter.com/wiki/hunter/perl_ironman/mount_multiple_apps_with_plack

If you in general use PSGI/Plack then you can use any Web server, also Starman or other Perl Web Servers. Which one you use is up to you. Use the one where you think it has the best performance, or the one which you knew the best.

Also think that when you start up your server you probably want to automatically start your application and Apache, Nginx, LightTPD, ... already have startup scripts. If you also want to host other websites then it is probably better to use one of these Webservers.

I prefer FastCGI for running your application. With FastCGI your application run independent from your Web Server, and can also run with other user rights, instead of mod_perl where all application runs under the same user as the Apache User. It also gives you the advantage that you can restart a application without restarting the complete Web Server (Apache).

Well and through that independent you probably need more RAM to run the same amounts of application, because you start your applications multiple times instead of use the sharing that gives you Apache/mod_perl.

In the end it depends on your needs for what is better.