これまで色々と Ruby を Azure Web サイトで動かす方法を考えてきましたが、やっと決定版という感じの方法を思いついたので紹介します。その前に Kudu のデプロイ周りの話を簡単に。
Kudu は Git からデプロイする際に、挙動をカスタマイズするための仕組みを持っています。
Customizing deployments · projectkudu/kudu Wiki · GitHub
Custom Deployment Script · projectkudu/kudu Wiki · GitHub
簡単に説明すると .deployment というファイルをリポジトリのルートに置いておくと、その中に書かれているコマンドをデプロイのタイミングで実行するという仕組みです。
Git などを使ってデプロイする場合には、Kudu がデフォルトのスクリプトを実行し MSBuild だったり KuduSync を使って、wwwroot 以下に配置してくれます。なので、このスクリプトをフックすれば、Ruby ランタイムのインストールや不足している gem のインストールを自動化できるのではないかと考えて、作成したのが以下のリポジトリにあるスクリプトです。
shibayan/AzureRubyDeployment · GitHub
メインとなるのは deploy.sh で、内部では指定されているバージョンの Ruby や Bundler がインストールされていない場合にはインストールを行い、Gemfile がリポジトリにあれば bundle install を実行してパッケージをインストールするようになっています。
ぐだぐだ書くのはやめて、そろそろ実際に試していくことにします。
Ruby on Rails アプリケーションを作成
まずは適当に rails コマンドを使ってテンプレートを作成します。
これ以上中身は書かず、とりあえずデフォルトのままで動くのか確認していきたいと思います。
.deployment / deploy.sh / startup.bat / Web.config を追加
shibayan/AzureRubyDeployment · GitHub からファイルを zip でダウンロードするか git clone するかして、ローカルに持ってきます。
必要なファイルは以下の 4 つになります。
- .deployment
- deploy.sh
- startup.bat
- Web.config
実際にデプロイで使っているのは .deployment と deploy.sh ですが、startup.bat と Web.config は Azure Web サイト上で動かすために必要になるので、一緒にコピーしておきます。
この中でも deploy.sh と Web.config には使用する Ruby のバージョンを定義している部分があるので、適宜修正を行います。今回は不具合の影響を避けるために 1.9.3 にしておきます。
RUBY_VERSION=1.9.3 RUBY_HOME="$DEPLOYMENT_TARGET/bin/ruby/$RUBY_VERSION"
<httpPlatform processPath="D:\home\site\wwwroot\startup.bat" arguments="" startupTimeLimit="60" startupRetryCount="5"> <environmentVariables> <environmentVariable name="RUBY_VERSION" value="1.9.3" /> </environmentVariables> </httpPlatform>
これでデプロイのタイミングで Ruby 1.9.3 がインストールされるようになります.
Gemfile に追記
このままデプロイするとサーバーが入らないので、Windows でも使える thin を使うことにします。
gem 'tzinfo-data' gem 'thin'
Gemfile に追記しておけば、デプロイしたタイミングで自動的にインストールされます。そして tzinfo-data も何故か一緒に入らないので追加しておきます。
Azure Web サイト上の Git を有効化
Azure Web サイトへは Git を使ってデプロイするので、管理ポータルから Git を有効化しておきます。
作成が終わると git remote add といったコマンド例が表示されるので、閉じずにおいておきます。
リポジトリを作成し、Azure Web サイト上の Git へプッシュ
git init を使ってリポジトリを作成し、適当にメッセージを入れてコミットします。
ここまではいいですね。
この後は git remote add コマンドを使って Azure Web サイトのリポジトリを azure という名前で追加し、git push azure master を実行します。*1
するとリモートでデプロイスクリプトが実行されて Ruby ランタイムのインストールが行われます。
ちなみに管理ポータルからもデプロイスクリプトが実行中であることを確認出来ます。
初回は Ruby ランタイムと同時に DevKit のインストールも行うので少し時間がかかります。
その後には Bundler をインストールし、さらに bundle install を実行するのでさらに時間がかかります。
しばらく待つとデプロイが完了します。時間はかかりますが、これは初回だけなので我慢してください。bundle install の実行中にエラーとなった場合には、kuduExec を使って直接 gem を叩く必要があります。
特にネイティブなライブラリを含む gem の時に問題になりやすい気がします。例えば json が今回インストール中にエラーとなってしまい、デプロイ自体が失敗しました。
仕方ないので kuduExec を使って、直接 gem install を実行してインストールを行います。*2
この後、管理ポータルから失敗したデプロイを選んで再デプロイを行えば、続きから始まります。
他にも Ruby 2.1.5 を使った場合には eventmachine で実行時エラーになったりします。これを修正するために、手動で gem を叩いてインストールします。
gem install eventmachine --platform=ruby
ABI が変わった影響で、Ruby 2.1.x では eventmachine のプリコンパイル版を使うと不具合が出るようです.
httpPlatformHandler + thin で動作を確認
startup.bat と Web.config で httpPlatformHandler と thin を使って動かすための設定を行っているので、デプロイが正常に完了した後であれば、そのままページを表示できるはずです。
とりあえず Ruby on Rails の基本的な画面まで確認出来ました。
カスタムデプロイスクリプトを使うことで、これまでみたいに Kudu のコンソールを立ち上げて環境を用意する必要がないので、多少は実用的になったのではないかと思います。