読者です 読者をやめる 読者になる 読者になる

Akihiro's Programmer Blog

Technology Notes for Personal

LocalhostでVirtualhostなAmon2

Amon2 Perl


やりたいこと

  • 一つのPlackアプリケーション内において、アプリ用と管理用のアプリケーションをホスト名で振り分けたい
  • でもお金がないので、開発環境は手元のマシン(Mac)で済ませたい
  • Amon2で


目次


LocalhostでVirtualhost

こちらを参考に設定しました。以下のファイルを編集していきます。


/private/etc/apatch2/httpd.conf

以下の行がコメントアウトされているので、コメントを外します。 

- #Include /private/etc/apache2/extra/httpd-vhosts.conf
+ Include /private/etc/apache2/extra/httpd-vhosts.conf

/private/etc/apache2/extra/httpd-vhosts.conf

中身を全て消して以下のように記述します。

<VirtualHost *:80>
    ServerName sample.localhost
    ProxyPass / http://localhost:5000
    ProxyPassReverse / http://localhost:5000
</VirtualHost>

<VirtualHost *:80>
    ServerName admin.sample.localhost
    ProxyPass / http://localhost:5000
    ProxyPassReverse / http://localhost:5000
</VirtualHost>

(追記: 2015/04/19)

@masasuz さんからコメントでご指摘がありました通り、以下の方が設定が膨らまず良いです。

<VirtualHost *:80>
    ServerName sample.localhost
    ServerAlias admin.sample.localhost
    ProxyPass / http://localhost:5000
    ProxyPassReverse / http://localhost:5000
</VirtualHost>

(余談)

ServerAliasについてググっていたら、同じ間違いをしていた方と記事名が似ていた

/private/etc/hosts

以下を追記します。

127.0.0.1   sample.localhost
127.0.0.1   admin.sample.localhost

最後にapatchを再起動して終わりです。

$ sudo apachectl restart


これで sample.localhost でも admin.sample.localhost でも localhost:5000 に向くようになりました。


Amon2でアプリケーションをホスト名振り分け

いくつかの実現方法があります。


Plack::Builder

#!perl
use strict;
use warnings;
use utf8;
use lib "lib";

use Plack::Builder;

use Sample::Web::App;
use Sample::Web::Admin;

my $app   = Sample::Web::App->to_app();
my $admin = Sample::Web::Admin->to_app();

builder {
    enable 'Plack::Middleware::ReverseProxy';

    mount "http://sample.localhost/"       => $app;
    mount "http://admin.sample.localhost/" => $admin;
};


Plack::App::URLMap

#!perl
use strict;
use warnings;
use utf8;
use lib "lib";

use Plack::Builder;
use Plack::App::URLMap;

use Sample::Web::App;
use Sample::Web::Admin;

my $app   = Sample::Web::App->to_app();
my $admin = Sample::Web::Admin->to_app();

builder {
    enable 'Plack::Middleware::ReverseProxy';

    my $url_map = Plack::App::URLMap->new;
    
    $url_map->map("http://sample.localhost/"       => $app);
    $url_map->map("http://admin.sample.localhost/" => $admin);

    $url_map->to_app;
};


Plack::App::HostMap

metacpan.org

#!perl
use strict;
use warnings;
use utf8;
use lib "lib";

use Plack::Builder;
use Plack::App::HostMap;

use Sample::Web::App;
use Sample::Web::Admin;

my $app   = Sample::Web::App->to_app();
my $admin = Sample::Web::Admin->to_app();

builder {
    enable 'Plack::Middleware::ReverseProxy';

    my $host_map = Plack::App::HostMap->new;

    $host_map->map("sample.*"       => $app);
    $host_map->map("admin.sample.*" => $admin);

    $host_map->to_app;
};


Plack::App::Vhost

#!perl
use strict;
use warnings;
use utf8;
use lib "lib";

use Plack::Builder;
use Plack::App::Vhost;

use Sample::Web::App;
use Sample::Web::Admin;

my $app   = Sample::Web::App->to_app();
my $admin = Sample::Web::Admin->to_app();

builder {
    enable 'Plack::Middleware::ReverseProxy';

    Plack::App::Vhost->new(
        vhosts => [
                   qr/^sample\./ => $app,
            qr/^admin\.sample\./ => $admin,
        ],
        fallback => sub {
            return [404, [], ["error"]];
        },
    )->to_app();
};


Plack::App::Hostname

#!perl
use strict;
use warnings;
use utf8;
use lib "lib";

use Plack::Builder;
use Plack::App::Hostname;

use Sample::Web::App;
use Sample::Web::Admin;

my $app   = Sample::Web::App->to_app();
my $admin = Sample::Web::Admin->to_app();

builder {
    enable 'Plack::Middleware::ReverseProxy';

    my $host_name = Plack::App::Hostname->new(
        default_app => sub { [200, [], ["default"]] }
    );
    
    $host_name->map_hosts_to($app   => 'sample.*'      );
    $host_name->map_hosts_to($admin => 'admin.sample.*');
    
    $host_name->to_app;
};


どれが良さそうか

Plack::App::Vhost が唯一正規表現でホスト名を表すことが出来るので、良さそう。