BlueberryStream Technical

@blueberrystreamが技術的なことを書くときに使うblogです。

ハンドサイン一覧ジェネレーターを作りました #appengine #php

作りました→ http://handsign-gen.appspot.com/

ソースコードはこちら→ blueberrystream/handsign-gen · GitHub

サイトデザインは相変わらず自分でやるよりいい感じにできる人からpull requestが来ればいいなーなんて思ってわざとやってません。本当はtweetできるようにするところまでやりたかったのですが、31日に突然流行りだしたネタなので、ともかく最低限使えるものをリリースしたいと考え、こんな形でのリリースになりました。急ぎましたが、ネタの鮮度がだいぶ落ちているので、あまり話題にはならないですね。

もし、評判がよければ Issues · blueberrystream/handsign-gen · GitHub に載せたこと、これから載るかもしれないことを実現していこうかなと思っています。

いまのところ、私のTwitterアカウントがprotectedなのもあって、大々的に拡散されてアクセススパイクが来るということはないのですが、身内で使ってくれる人がいてうれしい限りです。

 

さて、せっかくこちらの ぶるべりてくにか のblogに記事を書くわけなので、技術的なことをつらつらと書いていこうと思います。

注: 本当に技術的なことはここよりもっと下に書いてあります。

今回は動的な画像加工をプログラムからやるということなので、間借りしているVPS上だったり、お借りしているwebスペース*1でやるのはよろしくないと判断してApp Engineにしました。

当初は、プログラムから画像加工をするならどうするのが早いかなーってぼやいてたら

Lix先生がおっしゃる*2ので、ImageMagickのお世話になろうかと思ったのですが、AppEngineじゃ動かせるわけもなく…。そして、やりたいことはテンプレートの画像に文字を載せたいだけだったこともあり、PHPでGD関数を使うことにしました。

最近の流行に乗ってGo言語とかやってみたいと思っていますが、画像に文字を乗せるプログラムなんて書いたことがなかったので、ここは手に馴染んでいるとは言いがたいけど、Javaより素早く結果確認ができるPHPとなりました。

 

構成は、AppEngineでPHP、画像を扱うのはGD関数ってことで決まりました。お次は開発環境の構築です。AppEngine/PHPな環境はWindowsにもMac OS Xにも作っていなかったのでイチからの作業でした。push-to-deployができなくてハマったり、Google Cloud SDKをインストールしたらbashの様子がおかしくなったりで結局4時間くらいかかりました。1日目終了。

ようやく開発環境ができて、ちょこっと前に招待をもらったAtomを使って開発スタート。Development Serverで動かしながらある程度は形になってきたところで、Production Serverにdeployして動かしてみると動かない…ってところで2日目終了。これもだいたい4時間くらい作業したかな。

Production Serverだとテンプレートとなる画像にPHPからアクセスできなくて動かないという状況に陥り、結局はapp.yamlのhandler定義がよろしくなかっただけじゃんってことでリリースできたのが3日目でした。作業時間は2時間くらい。合計で10時間くらいで今回は初版リリースができました。

 

では、今回つまずいたところやおかしいなと思った点をまとめてみます。今回の開発はすべてMac OS X上で行いました。Windowsだとだいぶ勝手が違うかと思います。

push-to-deployができない

最初はDeveloper Consoleで表示されているリポジトリのURLをgit remote addしてpushすればいいだけだろ?って思ってたんですが、そんなことできようもなく…。これは、Git and Push-to-Deploy - Google App Engine — Google Developersに書いてあるように、

$ gcloud init PROJECT

としてやらないといけないわけです。でも、これをそのままやると、Googleアカウント情報を聞いてきます。正しく入力してもダメです。2段階認証のせいやろ〜と思ってアプリケーション固有パスワードを発行して使ってみてもダメです。正解は

$ gcloud auth login

としてあげることです。これで、gcloud init*3を実行できます。

この件は、ちゃんと公式文書を読みましょうってことに尽きますね。

Google Cloud SDKをインストールしたらbashの様子がおかしい

原因は、インストール時に~/.bash_profileなどに追記される

source /Users/temp/google-cloud-sdk/path.bash.inc

でした。path.bash.incの中身を見るまでもなく、Google Cloud SDKのbinをPATHに通そうとしてるわけですが、中身を見るとなんかごちゃごちゃやってたので、とりあえず上記の部分をコメントアウトしてディレクトリ直書きでPATHを通すことにして解決としました。根本的な原因はおそらく、bashでaliasを使いまくってる*4せいじゃないかなーと推測しています。

Production ServerでPHPから画像ファイルにアクセスできない

ログを見ると

PHP Warning:  imagecreatefrompng(../static/image/template.png): failed to open stream: No such file or directory in /base/data/home/apps/s~handsign-gen/dev.374851488411224157/script/gen.php on line 29

と出ています。パスの指定の仕方が悪いのかなーと変えてみたりしましたが、結局はapp.yamlのhandlerの書き方が悪かっただけのようでした。

修正前は

handlers:

- url: /

  static_files: static/index.html

  upload: static/index.html

 

- url: /(.+\.(html|css|js|txt|ico|gif|png|jpg))$

  static_files: static/\1

  upload: static/.+\.(html|css|js|txt|ico|gif|png|jpg)$

 

- url: /(.+\.php)$

  script: script/\1

 

- url: /image/template.png

  static_files: static/image/template.png

  upload: static/image/template.png

  application_readable: true

 としていましたが、

- url: /image/template.png

ではじまる部分を

- url: /(.+\.(html|css|js|txt|ico|gif|png|jpg))$

より上に持ってくるように修正しました。handlerは上から順番に見ていって一番最初に引っかかったものを使うということですね。

Development Serverでログを確認できない

これはかなり参りました。そして今も解決できていません。AppEngine PHPではsyslog関数でログ吐きができます。吐かれたログはProduction ServerではDeveloper Consoleから確認できます。しかし、Development ServerではGoogleAppEngineLauncher.appのログビューにも出てきません。どうやったら出るんだろう?どこに出てるんだろうといろいろ試した結果が以下です。

  • dev_appserver.pyにフラグ--log_level=debugを指定→出てこない
  • dev_appserver.pyにフラグ--log_files=hogehogeを指定→ちゃんと起動しない
  • まさかマジでsyslogに出てる?→syslog確認→出てない
  • Development ServerのAdmin ConsoleにあるInteractive ConsoleでLogs PHP API Overviewに載っているSample codeを動かす→取れたり取れなかったり→そもそもこんなアクセス方法を期待しているわけではない
  • php.iniに出力する最低ログレベルの設定があるのでは?→なさそう

というような感じです。Development Serverでログを確認する方法をぐぐって調べるも、たいていJavaについてばかりでした。Development Serverでログを確認する方法、詳細求ム…です。

フォントファイルをhandler定義に載せなくてもアクセスできる

今回のアプリではフォントファイルをプログラムで読み込むのですが、上述のPHPから画像ファイルにアクセスできない件で晒したapp.yamlのようにフォントファイル(*.ttf)についての定義がありません。画像のように

application_readable: true

と書いていないということです。しかし、Production Serverでも普通にPHPから読めているようです。謎です。

 

いまさらPHPかよって感じではありますが、ログの件とフォントファイルの件はおわかりになる方がいればぜひ教えていただきたいです。おねがいします。

*1:kid0725.usamimi.infoのこと

*2:こういうときにちょろっとアドバイスというかアイディアをくれるLix先生は本当に素敵だと思います

*3:initってついてますが、実際はリモートのリポジトリをcloneしてくるようです

*4:cdすると自動的にls -lApするようにしてたりする