Hatena::ブログ(Diary)

hsksnote RSSフィード Twitter

2011-12-05

Amon2のLarge flavorをDotCloudで動かしたら、staticファイルが参照できなかった。

Amon2のamon2-setup.pl --flavor=DotCloud,Largeで作ったスケルトンをDotCloudで動かしたら、staticの下にあるcssjsファイルが参照できなかった。

解決どころか問題箇所の特定もできなかったが、とりあえず事象と怪しいところをメモっておく。


再現

以下の手順でスケルトンを作ってDotCloudに上げる。

$ amon2-setup.pl --flavor=DotCloud,Large LargeApp
$ cd LargeApp
$ dotcloud push largeapp ./

これで、できたアプリケーションアクセスする。

f:id:hsksnote:20111205232600p:image

CSSjsが効いてない。

ログを見ると、static以下のファイルが見つからないと言われてる。

$ dotcloud logs largeapp.www
#  tail -F /var/log/{supervisor,nginx}/*.log 
==> /var/log/nginx/largeapp-default-www-0.error.log <==
2011/12/05 10:35:42 [error] 7602#0: *11 open() "/home/dotcloud/current/static/css/main.css" failed (2: No such file or directory), client: 10.192.170.48, server: largeapp-default-www-0, request: "GET /static/css/main.css?t=0 HTTP/1.0", host: "largeapp-hsksyusk.dotcloud.com", referrer: "http://largeapp-hsksyusk.dotcloud.com/"

ブラウザからソースを見ると、ここを見に行っているが、

実際にはこのURLアクセスできる。


URLマッピング

実際のディレクトリ構成としては、static/pcの下にある構成なのだけど、URLマッピングでstatic下にあるように見えるようにしているハズなので、たぶんマッピングがうまくいってないのであろう。

マッピングはapp.psgiでやってる。

app.psgi

use strict;
use utf8;
use File::Spec;
use File::Basename;
use lib File::Spec->catdir(dirname(__FILE__), 'extlib', 'lib', 'perl5');
use lib File::Spec->catdir(dirname(__FILE__), 'lib');
use Plack::Builder;

use LargeApp::PC;
use Plack::Util;
use Plack::Builder;

builder {
    mount '/admin/' => Plack::Util::load_psgi('admin.psgi');
    mount '/' => Plack::Util::load_psgi('pc.psgi');
};

load_psgiで他のpsgiファイルを読んでいる。admin.psgiは管理画面を作る場合のマッピングで、普通にサービスにアクセスするのはpc.psgiで設定されている。

pc.psgi

use strict;
use utf8;
use File::Spec;
use File::Basename;
use lib File::Spec->catdir(dirname(__FILE__), 'extlib', 'lib', 'perl5');
use lib File::Spec->catdir(dirname(__FILE__), 'lib');
use Plack::Builder;

use LargeApp::PC;
use Plack::App::File;
use Plack::Util;
use Plack::Session::Store::DBI;
use Plack::Session::State::Cookie;
use DBI;

my $basedir = File::Spec->rel2abs(dirname(__FILE__));
my $db_config = LargeApp->config->{DBI} || die "Missing configuration for DBI";
{
    my $c = LargeApp->new();
    $c->setup_schema();
}
builder {
    enable 'Plack::Middleware::Static',
        path => qr{^(?:/robots\.txt|/favicon\.ico)$},
        root => File::Spec->catdir(dirname(__FILE__), 'static', 'pc');
    enable 'Plack::Middleware::ReverseProxy';
    enable 'Plack::Middleware::Session',
        store => Plack::Session::Store::DBI->new(
            get_dbh => sub {
                DBI->connect( @$db_config )
                    or die $DBI::errstr;
            }
        ),
        state => Plack::Session::State::Cookie->new(
            httponly => 1,
        );

    mount '/static/' => Plack::App::File->new(root => File::Spec->catdir($basedir, 'static', 'pc'));
    mount '/' => LargeApp::PC->to_app();
};

たぶんこのあたりのどこかが問題なんだろうと思うけど、全然わからないのでギブアップ。


ちなみにLarge flavorではなくBasic flavorだと、DotCloud上でも問題なく動く。こちらのapp.psgiはこんなです。

app.psgi(Basic flavor)

use strict;
use utf8;
use File::Spec;
use File::Basename;
use lib File::Spec->catdir(dirname(__FILE__), 'extlib', 'lib', 'perl5');
use lib File::Spec->catdir(dirname(__FILE__), 'lib');
use Plack::Builder;

use BasicApp::Web;
use BasicApp;
use Plack::Session::Store::DBI;
use Plack::Session::State::Cookie;
use DBI;

{
    my $c = BasicApp->new();
    $c->setup_schema();
}
my $db_config = BasicApp->config->{DBI} || die "Missing configuration for DBI";
builder {
    enable 'Plack::Middleware::Static',
        path => qr{^(?:/static/)},
        root => File::Spec->catdir(dirname(__FILE__));
    enable 'Plack::Middleware::Static',
        path => qr{^(?:/robots\.txt|/favicon\.ico)$},
        root => File::Spec->catdir(dirname(__FILE__), 'static');
    enable 'Plack::Middleware::ReverseProxy';
    enable 'Plack::Middleware::Session',
        store => Plack::Session::Store::DBI->new(
            get_dbh => sub {
                DBI->connect( @$db_config )
                    or die $DBI::errstr;
            }
        ),
        state => Plack::Session::State::Cookie->new(
            httponly => 1,
        );
    BasicApp::Web->to_app();
};

ちなみにローカルでplackupで動かすと、Largeでも問題なく表示できる。

f:id:hsksnote:20111205232601p:image


なんでなんだぜ。


追記(2012/12/11)

id:tokuhiromさんからいただいたコメントを参考に、以下のファイルを作成したところ、staticのファイルが参照できるようになった。

nginx.conf

rewrite ^/static/(.*) /static/pc/$1 last;

このファイルをローカルのトップに置いて、git addしてgit commitしてdotcloud pushしたら、/home/dotcloud/current/nginx.confができてうまくいった。

でも/adminの方のstaticはどう参照させればいいのかわからない感じです。

tokuhiromtokuhirom 2011/12/07 11:15 すみません。Large フレーバーは DotCloud flavor に対応してません。dotcloud は static/ を ngingx でだしてるので nginx.conf をがんばってかえればでるようになるかとおもいます。

hsksyuskhsksyusk 2011/12/11 00:14 tokuhiromさん
コメントありがとうございます!参考にしてちょっといじってみて一部うまくいった感じを追記しました。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/hsksnote/20111205/1323095297
リンク元