2015-06-15

drop7 を Cloud Foundry で動かす

本日の第8回「Cloud Foundry 百日行」は、drop7です。
これも簡単な構成のWebアプリゲームです。
内容は相変わらず簡単なHTML+Javascriptですが徐々に追加の内容を盛り込んでいこうと思います。

drop7基本情報

デプロイ

手順

  • 0) 準備
  • 1) アプリの起動?
  • 2) 動作確認その1
  • 3) アプリの起動
  • 4) 動作確認その2

0.準備

まずはソースコードの取得から。

$ git clone https://github.com/pavellishin/drop7
$ cd drop7
drop7$ ls
defs.js  drop7.css  drop7.html  drop7.js  drop7.manifest  jquery-1.9.1.min.js  revision.hook  take1  take2

1.アプリの起動?

これまで通りCloud Foundry上にアプリをデプロイしてみましょう。
後々のためにmanifestファイルを作ってしまいます。

drop7$ vi manifest.yml
---
applications:
- name: drop7
  buildpack: https://github.com/cloudfoundry/staticfile-buildpack
  memory: 4M
  disk_quota: 16M

こんな所でしょうか。
デプロイをしてみます。

drop7$ cf push
Using manifest file /home/ukaji/workspace/drop7/manifest.yml

Creating app drop7 in org ukaji / space default as ukaji...
OK

Creating route drop7.10.244.0.34.xip.io...
OK

Binding drop7.10.244.0.34.xip.io to drop7...
OK

Uploading drop7...
Uploading app files from: /home/ukaji/workspace/drop7
Uploading 218.3K, 16 files
Done uploading               
OK

Starting app drop7 in org ukaji / space default as ukaji...
-----> Downloaded app package (80K)
Cloning into '/tmp/buildpacks/staticfile-buildpack'...
Submodule 'compile-extensions' (https://github.com/cloudfoundry-incubator/compile-extensions.git) registered for path 'compile-extensions'
Cloning into 'compile-extensions'...
Submodule path 'compile-extensions': checked out '0b1eb13f9a747494b0abac8c665bb556cd07c749'
grep: Staticfile: No such file or directory
-----> Using root folder
-----> Copying project files into public/
-----> Setting up nginx
grep: Staticfile: No such file or directory
-----> Uploading droplet (2.3M)

1 of 1 instances running

App started


OK

App drop7 was started using this command `sh boot.sh`

Showing health and status for app drop7 in org ukaji / space default as ukaji...
OK

requested state: started
instances: 1/1
usage: 4M x 1 instances
urls: drop7.10.244.0.34.xip.io
last uploaded: Tue Jun 9 05:12:57 +0000 2015
stack: lucid64

     state     since                    cpu    memory       disk       details   
#0   running   2015-06-09 02:13:41 PM   0.0%   2.4M of 4M   0 of 16M

無事起動したようです。

2.動作確認その1

動作確認を行います。
ブラウザでアクセスをしてみましょう。

403エラーが出てしまいました。

そこまで込み入った話でもないのでネタバレをしてしまうと、実はdrop7.10.244.0.34.xip.ioにアクセスした時に呼ばれているファイルは、アプリケーションのルートディレクトリにあるindex.htmlです。
今回のアプリケーションの中身を眺めてみると、最初に呼び出したいファイルはdrop7.htmlのようですが、デフォルトの設定ではこれを呼ぶことができなかったため、エラーが返ってきてしまったと考えられます。

drop7.htmlのファイル名をindex.htmlに書き換えてしまえば良い話ではあるのですが、もし他のファイルからdrop7.htmlが呼ばれていたりすると少々厄介です。
どうにかして最初に呼ぶファイルをdrop7.htmlに変更してしまう方が何かと便利そうです。

3.アプリの起動

ということで、今回はStaticfile-buildpackが提供する機能を使ってみます。
Staticfile-buildpackのConfigurationの項目を読んでみると、Advanced Nginx configurationという項目があります。
Staticfile-buildpackはHTMLなどのアプリのためにNginxによってHTTPサーバを立ててくれるのですが、どうやらCloud Foundry上に立てられるNginxの設定ファイルnginx.confを書きかえることができるようです。

では、Staticfile-buildpackのリポジトリ内にあるnginx.conf
https://github.com/cloudfoundry/staticfile-buildpack/blob/master/conf/nginx.conf
こちらを例にして設定ファイルを作ってみます。
・・・と言っても書き換えるのは24行目のindexの部分だけ。
ここにdrop7.htmlを追加しましょう。

drop7$ vi nginx.conf
worker_processes 1;
daemon off;

error_log <%= ENV["APP_ROOT"] %>/nginx/logs/error.log;
events { worker_connections 1024; }

http {
  log_format cloudfoundry '$http_x_forwarded_for - $http_referer - [$time_local] "$request" $status $body_bytes_sent';
  access_log <%= ENV["APP_ROOT"] %>/nginx/logs/access.log cloudfoundry;
  default_type application/octet-stream;
  include mime.types;
  sendfile on;
  gzip on;
  tcp_nopush on;
  keepalive_timeout 30;
  port_in_redirect off; # Ensure that redirects don't include the internal container PORT - <%= ENV["PORT"] %>

  server {
    listen <%= ENV["PORT"] %>;
    server_name localhost;

    location / {
      root <%= ENV["APP_ROOT"] %>/public;
      index index.html index.htm Default.htm drop7.html;
      <% if File.exists?(File.join(ENV["APP_ROOT"], "nginx/conf/.enable_directory_index")) %>
      autoindex on;
      <% end %>
      <% if File.exists?(auth_file = File.join(ENV["APP_ROOT"], "nginx/conf/.htpasswd")) %>
      auth_basic "Restricted";                                #For Basic Auth
      auth_basic_user_file <%= auth_file %>;  #For Basic Auth
      <% end %>
      <% if ENV["FORCE_HTTPS"] %>
      if ($http_x_forwarded_proto = http) {
        return 301 https://$host$request_uri;
      }
      <% end %>
    }
  }
}

※変更箇所

drop7$ diff nginx.conf_default nginx.conf 
24c24
<       index index.html index.htm Default.htm;
---
>       index index.html index.htm Default.htm drop7.html;

もちろん、nginx.confファイルをご自身で書ける方は他にも色々な設定を加えてみてもいいかもしれません。

さて、今度こそアプリケーションを動かしてみましょう。
nginx.confはアプリのルートディレクトリに置いておくだけでいいそうなのでこのままデプロイで問題なさそうです。

drop7$ cf push
(一部略)
requested state: started
instances: 1/1
usage: 4M x 1 instances
urls: drop7.10.244.0.34.xip.io
last uploaded: Tue Jun 9 05:22:47 +0000 2015
stack: lucid64

     state     since                    cpu    memory       disk       details   
#0   running   2015-06-09 02:23:41 PM   0.0%   2.3M of 4M   0 of 16M

起動はもちろん成功。

4.動作確認その2

URLにアクセスしてみましょう。

今回は無事アクセスができました。

ちなみにゲームの基本的なルールですが・・・

  • 1.縦もしくは横に並んだボールのうち、列の個数と同じ番号のボールが消える
  • 2.数字の書いていないボールは周りのボールを2回壊せば中からボールが出てくる

こんなところでしょうか。あとは大体世の中の落ち物ゲームと同じような感じだと思います。
何にせよ言葉で説明するのは少し難しいので、習うより慣れろでプレイしてみるのが一番だと思います。

おわりに

毎回HTML+Javascriptのアプリケーションを同じように解説するのは少し味気ないので、今回はBuildpackが提供する追加機能に触れてみました。
Githubのページをご覧の通り、他にも簡単なBASIC認証などの機能も実装されています。
動作検証を行ったアプリの中にはまだHTML系のアプリケーションも残っているので、いずれそちらも解説するかもしれません。

今回使用したソフトウェア