beanstalkでCGIを動かしてみた(AMIカスタマイズ編)
初期状態のAWS Elastic beanstalkでは、CGIを動かす事ができないので、動かせるようにしてみた。
準備
前回の記事を参考に、php5アプリケーションをdeployして環境を動かしておきます。
CGIを置いてみる
ひとまず試しにCGIファイルを置いてみます。
~/work/php5 $ cat test.cgi #!/usr/bin/perl print <<EOF; Content-type:text/plain this is cgi test on beanstalk EOF ~/work/php5 $ chmod +x test.cgi ~/work/php5 $ ./test.cgi Content-type:text/plain this is cgi test on beanstalk ~/work/php5 $ git add test.cgi ~/work/php5 $ git commit -m "add cgi" [master 974051d] add cgi 1 files changed, 7 insertions(+), 0 deletions(-) create mode 100755 test.cgi ~/work/php5 $ git aws.push Counting objects: 5, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (4/4), 416 bytes, done. Total 4 (delta 0), reused 0 (delta 0) remote: To https://ACCESSKEY:SIGNATURE@git.elasticbeanstalk.us-east-1.amazonaws.com/repos/70687035/php5test 71d6bba..974051d HEAD -> master ~/work/php5 $ curl http://php5test.elasticbeanstalk.com/test.cgi #!/usr/bin/perl print <<EOF; Content-type:text/plain this is cgi test on beanstalk EOF
プログラムがそのまま出ちゃいました。どうやら、サーバ側でCGIが認識されないような設定になっているようです。.htaccessで追加してみましょう。
~/work/php5 $ cat .htaccess AddHandler cgi-script cgi Options +ExecCGI ~/work/php5 $ git add .htaccess ~/work/php5 $ git commit -am "add ExecCGI" [master ecaba42] add ExecCGI 1 files changed, 1 insertions(+), 0 deletions(-) ~/work/php5 $ git aws.push Counting objects: 5, done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 349 bytes, done. Total 3 (delta 0), reused 0 (delta 0) remote: To https://ACCESSKEY:SIGNATURE@git.elasticbeanstalk.us-east-1.amazonaws.com/repos/70687035/php5test 974051d..ecaba42 HEAD -> master ~/work/php5 $ curl http://php5test.elasticbeanstalk.com/test.cgi <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>500 Internal Server Error</title> </head><body> <h1>Internal Server Error</h1> <p>The server encountered an internal error or misconfiguration and was unable to complete your request.</p> <p>Please contact the server administrator, root@localhost and inform them of the time the error occurred, and anything you might have done that may have caused the error.</p> <p>More information about this error may be available in the server error log.</p> <hr> <address>Apache/2.2.22 (Amazon) Server at php5test.elasticbeanstalk.com Port 80</address> </body></html>
少し前進。エラーメッセージが変わりました。Internal Server Errorになっているようです。実際にインスタンスにログインしてログを調べてみると...
# cat /var/log/httpd/application-error_log [Wed Apr 04 09:45:55 2012] [error] [client 10.209.199.0] Options ExecCGI is off in this directory: /var/www/html/test.cgi [Wed Apr 04 09:48:36 2012] [error] [client 10.209.199.0] (13)Permission denied: exec of '/var/www/html/test.cgi' failed [Wed Apr 04 09:48:36 2012] [error] [client 10.209.199.0] Premature end of script headers: test.cgi
oh, Permission deniedのようです。deploy前にchmod +xしたはずなのですが。
# ls -al /var/www/html/test.cgi -rw-r--r-- 1 elasticbeanstalk elasticbeanstalk 88 Apr 4 09:48 /var/www/html/test.cgi
なんてこったい、実行権限が落ちてます。色々と調べていると、deployの際にこんなスクリプトが呼ばれていました。
# grep chmod /tmp/php_deploy_app.sh /usr/bin/sudo /bin/chmod -Rf 0755 /tmp/php-elasticbeanstalk-deployment/application /bin/find /tmp/php-elasticbeanstalk-deployment/application -type f -print0 | /usr/bin/xargs -0 /bin/chmod 0644
とりあえず755にしておいて、ファイルすべてを644にするという方法のようです。PHPなら644でも動きますので、一応理にかなってはいますが。
このスクリプトは、/opt/elasticbeanstalk/srv/hostmanager/lib/elasticbeanstalk/hostmanager/applications/phpapplication.rb で都度生成されるようですので、パッチ当てます(2つめの644にする部分をコメントアウト)。
~/work/php5 $ git diff diff --git a/test.cgi b/test.cgi index 4cb7af5..1c0375a 100755 --- a/test.cgi +++ b/test.cgi @@ -2,5 +2,5 @@ print <<EOF; Content-type:text/plain -this is cgi test on beanstalk +this is cgi test on beanstalk! EOF ~/work/php5 $ git commit -am 'touch!' [master 0b896e4] touch! 1 files changed, 1 insertions(+), 1 deletions(-) ~/work/php5 $ git aws.push Counting objects: 5, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 271 bytes, done. Total 3 (delta 2), reused 0 (delta 0) remote: To https://ACCESSID:SIGNATURE@git.elasticbeanstalk.us-east-1.amazonaws.com/repos/70687035/php5test ecaba42..0b896e4 HEAD -> master ~/work/php5 $ curl http://php5test.elasticbeanstalk.com/test.cgi this is cgi test on beanstalk!
落とし穴
しかし、このインスタンスをTerminateして落としてしまうと、しばらくして別のインスタンスが自動的に起動して復旧するはするのですが、
~/work/php5 $ curl http://php5test.elasticbeanstalk.com/test.cgi #!/usr/bin/perl print <<EOF; Content-type:text/plain this is cgi test on beanstalk! EOF
と、元の状態にもどってしまいます。これは、PHP5.3用のBeanstalk AMIを使用しているためとなります。そこで、カスタムAMIを作成します。
カスタムAMI作成
BeanstalkからだとAutoScaling経由となってしまうので、Beanstalkからではなく直接AMIを指定してカスタマイズ用のインスタンスを起動します。
64bitであれば、PHPBeanstalk64-2012.03.30 (ami-f759879e)が該当します。このAMIを利用してインスタンスを立ち上げ、上記のパッチ(cmod 0644を行う行をコメントアウト)を行い、CreateImageでAMIにします。
環境設定変更
Environmentの設定を変更し、カスタムAMIを使用するようにします。
しばらくするとインスタンスが入れ替わり、StatusがGREENに戻ったら確認します。
~/work/php5 $ curl http://php5test.elasticbeanstalk.com/test.cgi this is cgi test on beanstalk!
無事に入れ替わりました!
まとめ
今回は単にCGIを有効にしたいという物でしたが、色々なライブラリなどを追加したAMIが欲しい場合などには、このようにして作成してください。