DotCloud で PHP アプリを設置してみたときの色々
beta の invite もらったので DotCloud で遊んでみました。
アプリ1つくらい設置してみないとなんだかよくわからないよねってことで、とりあえずどこで公開するかなーと思っていた、paste アプリ を設置してみた。
- Pastit: http://www.pastit.dotcloud.com/
- Pastit GitHub: https://github.com/sotarok/pastit/
DotCloud の PHP の環境は、Ubuntu 上の nginx + php5-fpm (PHP 5.3.2) が標準で、なんというか時代の流れを感じました。いいね!
のは、まあいいとして、まぁ PHP アプリなんてものはたいてい Apache で動くことが前提とされてるもので (そうなのか? いや、そうだと思う。それが PHP のメリットだし) nginx な環境とか全然考慮してなかった + そんな PHP ユーザな弊害として nginx 力が低すぎてアレだったのですこしばかりはまったので、まあそのあたりのメモとして。
ということで、話は Pastit のディレクトリ構成を前提に進めますが、GitHub にあがってるので参考にしてください。
主な話の内容は、
- DotCloud のアプリ設置操作
- DotCloud の環境とか
- DotCloud + PHP + nginx の環境とか
とりあえず設定
まあ Tutorial で言われてるとおりコマンドをインストールして、アプリケーションサーバと MySQLサーバをつくってみる。
最初に dotcloud コマンドを使ったときに token をセットしろっていわれるけどこれはログインして setting を見たときに書いてあるやつな。
$ dotcloud list $ dotcloud create pastit $ dotcloud deploy --type php pastit.www $ dotcloud deploy --type mysql pastit.mysql
MySQL の設定とかは以下で確認
$ dotcloud info pastit.mysql cluster: wolverine config: mysql_password: **** created_at: 1304535584.4373901 name: pastit.mysql namespace: pastit ports: - name: mysql url: mysql://root:****@mysql.pastit.dotcloud.com:port - name: ssh url: ssh://dotcloud@mysql.pastit.dotcloud.com:port state: running type: mysql
MySQL は、以下でログインできるので、これでログインして DB 作ったりユーザ作ったりする。
$ dotcloud run pastit.mysql -- mysql -uroot -p\'****\'
で、ソースコードのデプロイ。今回は Git リポジトリです。Pastitのリポジトリのルートで実行。Gitのブランチを指定する場合は -b で。しなければ master が push される。
$ dotcloud push -b develop pastit.www .
で、http://www.pastit.dotcloud.com/ で動けばOK。今回は pastit.www という名前でデプロイしてるからこのURLになるけど、pastit.* に当たる部分が URL のサブドメイン *.pastit.dotcloud.com になる。
前提として知っておくべき DotColud の環境
push するとなにがどう設置されるか
DotCloud に push すると、以下のようなディレクトリ構成で設置される。とりあえず type = PHP の場合の話だが、アプリケーションサーバの場合他のタイプでも大差ないだろう。
dotcloud@pastit-www:~$ pwd /home/dotcloud dotcloud@pastit-www:~$ ls -la -rw-r--r-- 1 dotcloud www-data 54722 2011-05-06 18:53 build.log drwxr-xr-x 13 dotcloud www-data 4096 2011-05-06 18:53 c1bda3a lrwxrwxrwx 1 root root 7 2011-05-06 18:53 code -> c1bda3a lrwxrwxrwx 1 dotcloud www-data 8 2011-05-06 18:53 current -> code/www
この c1bda3a ってやつがコードの実態。
今回の場合リポジトリが Git だったので Git でのデプロイした時のコミットオブジェクトの hash 値になっている。
code ってやつは、常に最新のソースのルートへの symlink になっている。
current ってやつも symlink で、ここがアプリケーションの root (ドキュメントルート的な) の場所を指し示す。ここは、特に何も設定しなければ、 code と同じ場所を指すが、次に説明する dotcloud_build.yml で設定することで変更できる。
capistrano とかを使ったことがあれば、ソースコードが配置されて、最新のツリーへの symlink があって、みたいな構成はだいたい同じなのでキャッチアップしやすいと思う。
dotcloud_build.yml
DotCloud にアプリを push をすると、そのディレクトリをドキュメントルート *1 として設置される。多くのフレームワークのアプリの場合これは好ましくないはず。
なので、そのへんを設定してあげるのが docloud_build.yml。ここに、アプリの root がどこなのかという設定を記述できる (その他の設定項目もあるがとりあえずは省略) 。
このファイルは push するディレクトリのルートにおいておく。今回は approot として www ディレクトリを指定。
www: approot: www
nginx.conf と fastcgi.conf
approot 以下においておくと、読み込んでくれる nginx の設定。
といっても、Apache の .htaccess とはちがって、単に nginx の設定で include されてるだけだから、pushしたときに nginx が reload されてはじめて設定は適用される。
両者の違いは、
というだけ。これは設定が include される場所が違うだけ。PHP に関する設定は fastcgi.conf にしておくのがよさそう。
nginx.conf と fastcgi.conf は、deny 設定されてたのに、次に説明する postinstall だけ deny されてなかったので、それを nginx.conf に書いておいた。あと try_files の設定 (後述)。
try_files $uri $uri/ /index.php?$args; location = /postinstall { deny all; }
postinstall
いかにも Debian 好きっぽそうなこの名前は、approot 以下に実行ファイルとしておいておくと、push の最後に実行してくれる。アプリケーションの設定の適用を行うファイルとかを適切においておけば良い。
ちなみに、Pastit は Ethna の config を home においておいて、それを push 時に適切なディレクトリにコピーするようにしている。PHP厨らしくちゃんとPHPで記述しておく。
#!/usr/bin/php <?php define('DOTCLOUD_HOME', '/home/dotcloud/'); $files = array( 'pastit-ini.php' => 'code/config/pastit-ini.php', 'pastit-app-ini.php' => 'code/config/pastit-app-ini.php', ); foreach ($files as $origin_file => $dest_file) { if (!file_exists(DOTCLOUD_HOME . $dest_file) && file_exists(DOTCLOUD_HOME . $origin_file)) { echo DOTCLOUD_HOME . $origin_file, " -> ", DOTCLOUD_HOME . $dest_file, PHP_EOL; copy(DOTCLOUD_HOME . $origin_file, DOTCLOUD_HOME . $dest_file); } } // task echo 'end of task', PHP_EOL;
その他
まあ ssh で入って /etc/nginx 以下をのぞけばわかることだけど、
- favicon.ico は current/static/favicon.ico (approot/static/favicon.ico) を参照される
- robots.txt も current/static/robots.txt を参照される
nginx x PHP な設定
PAHT_INFO とか
PATH_INFO使ってる人ってどれだけいるのかわからないけど Ethna の UrlHandler はそれ使って path 解析するから、あるといい。
んだけど、PHP で一般的に知られている nginx 向けの PATH_INFO の設定だと、location が
/.+\.php.+$
にマッチするのが前提だったりしなくもないので、それだと、DotCloud 的にはよろしくない。というのは、DotCloud の PHP 向けの nginx の設定が
location ~ /.+\.php$ { if ( -f /home/dotcloud/current/maintenance) { return 503; } try_files $uri /static/404.html; fastcgi_pass unix:/var/dotcloud/php5-fpm.sock; include fastcgi_params; include /home/dotcloud/current/*fastcgi.conf; }
となっているので、index.php/hoge とかにマッチしてくれない。
ならば /.+\.php.+$ にマッチする設定を approot/nginx.conf に書いておけば良いのかもしれないけど、fastcgi_pass のような DotCloud 環境依存な設定がそっちに記述されるのもどうかなと思うので、ここはゴリ押しで解決させておく。
index.php の先頭でこんなかんじで PATH_INFO のセットをしておいた
<?php if (!isset($_SERVER['PATH_INFO'])) { $request_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; if (!empty($request_uri)) { $parsed_uri = parse_url($request_uri); $request_uri = isset($parsed_uri['path']) ? $parsed_uri['path'] : ''; } $_SERVER['PATH_INFO'] = $request_uri; }
rewrite とか
このあたりは DotCloud の Tutorial にあるように、try_files で設定しておくのがよさそう。$args も忘れずに。
try_files $uri $uri/ /index.php?$args;
よくある nginx.conf の設定だとここで
/index.php$requrest_uri
などをしておくことで PATH_INFO は設定するんだけど、そもそもこれは前述のとおり location でマッチできなくなるのでだめだった、というわけです。
まとめと雑感
- DotCloud いいかんじ
- サーバ建てるのとかデプロイとか超楽
- PaaS的なものが増えてきてほんとアプリケーションエンジニアがインフラ触る機会って今後減ってくるんだろうなーと思った
- Apache で簡単に動く PHP も好きだけど nginx な環境も最近は割と簡単に揃うし FPM とかも徐々に使われるようになるのかなーと思いつつ、色々な環境で動かせるようにしておくのは、たしかによさそう *2
- まあいずれにしても Apache べったり、じゃなくてもいい時代かもね
- DotCloud はその他ミドルウェアも充実してるからいろいろ遊びたいなー
- あ、ってことで Pastit っていう、設置型ペーストアプリを公開しました。これはもとも Internal な環境で (社内とか) snippet の共有が簡単にできるといいなーと思って作ったので、使いたい方は設置してみるといいかもしれません、結構便利ですよ。まだ embed できないけど。