VPSサーバでSinatraを動かしたい
前回はhaphostのVPSサーバの基本設定を行いました。VPSサーバは、RubyとPythonの学習のために借りているようなところがあります。今回は、このサーバ上でRubyの軽量WebフレームワークであるSinatraを動かしてみます。
/optにrbenvでRuby実行環境を構築
Rubyの実行環境はrbevnで構築します。通常は「$HOME/.rbenv」などにインストールすると思いますが、今回は本番環境ということもあり「/opt/rbenv」にインストールしてみます。
rbenvはgithubから取得するので、先ずは、gitとRubyのコンパイルに必要なパッケージを取得します。
$ sudo apt-get install git libssl-dev build-essential libreadline6-dev zlib1g-dev apache2-threaded-dev libcurl4-openssl-dev
今回は、/opt/rbenvはrbenvユーザの所有ディレクトリとして構築します。Debianにrbenvユーザを追加します。
$ sudo useradd -u 2000 -d /opt/rbenv -s /bin/bash rbenv
githubからrbenvを取得し、rbenvユーザのディレクトリとします。
$ sudo git clone <a href="https://github.com/sstephenson/rbenv.git">https://github.com/sstephenson/rbenv.git</a> /opt/rbenv $ sudo git clone <a href="https://github.com/sstephenson/ruby-build.git">https://github.com/sstephenson/ruby-build.git</a> /opt/rbenv/plugins/ruby-build $ sudo chown -R rbenv:rbenv /opt/rbenv
rbenvユーザのHOMEディレクトリ(/opt/rbenv)に以下設定を行います。これで、rbenvユーザがrbenvを利用可能になります。
$ sudo -u rbenv vi /opt/rbenv/.bash_profile export RBENV_ROOT=/opt/rbenv export PATH="$RBENV_ROOT/bin:$PATH" eval "$(rbenv init -)"
rbenvユーザになり、現時点(2015年1月)で最新のRuby 2.2.0をインストールします。
$ sudo su - rbenv rbenv@haphost:~$ rbenv install 2.2.0 rbenv@haphost:~$ rbenv global 2.2.0
Ruby 2.2.0がインストールできました。
Sinatraで作成したアプリは、Apache + passengerで公開します。bundlerとpassengerだけをgemで/opt/rbenv配下に導入します。他のパッケージはアプリ単位で管理することとします。
rbenv@haphost:~$ gem install bundler passenger
これで、Ruby実行環境の構築は完了です。。。と言いたいところでしたが問題が発生しました。passengerインストール後は、passenger-install-apache2-moduleコマンドでApacheモジュールをビルドする必要があります。
rbenv@haphost:~$ /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/passenger-4.0.57/bin/passenger-install-apache2-module Compiling Phusion Passenger works best when you have at least 1024 MB of virtual memory. However your system only has 256 MB of total virtual memory (128 MB RAM, 128 MB swap). It is recommended that you temporarily add more swap space before proceeding. You can do it as follows: sudo dd if=/dev/zero of=/swap bs=1M count=1024 sudo mkswap /swap sudo swapon /swap
メモリが足りなくてコンパイルできないようです。swap追加するように指示されていますが、haphostはOpenVZでVPSが提供されているためswapの追加ができません。
途方にくれ、一瞬 nginx + unicorn にすることも考えました。しかし、冷静に考えてみればメモリが足りなくてコンパイルできないだけです。他の環境で/opt/rbenvを作成して、コピーすれば動く気がします。
こんな時こそ、DigitalOceanの出番です。HaphostのVPSではDebian 7(wheezy)で構築しています。同様に、Debian 7でインスタンス(Droplet)を作成しました。$0.007/hourで利用できる最安のインスタンスを使います。メモリは512Mしかないので、haphostと同様にpassengerのコンパイルができません。そこでswapを1024Mを追加します。
$ sudo mkdir /opt/swap $ sudo dd if=/dev/zero of=/opt/swap/swap1 bs=1M count=1024 $ sudo mkswap /opt/swap/swap1 $ sudo swapon /opt/swap/swap1
十分にswapも増やせたので、haphostと同様の手順で/opt/rbenvを構築します。gemでpassengerをインストール後Apacheモジュールをコンパイルしてみます。
rbenv@debian:~$ /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/passenger-4.0.57/bin/passenger-install-apache2-module Almost there! Please edit your Apache configuration file, and add these lines: LoadModule passenger_module /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/passenger-4.0.57/buildout/apache2/mod_passenger.so <IfModule mod_passenger.c> PassengerRoot /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/passenger-4.0.57 PassengerDefaultRuby /opt/rbenv/versions/2.2.0/bin/ruby </IfModule> After you restart Apache, you are ready to deploy any number of web applications on Apache, with a minimum amount of configuration! <VirtualHost *:80> ServerName <a href="http://www.yourhost.com">www.yourhost.com</a> # !!! Be sure to point DocumentRoot to 'public'! DocumentRoot /somewhere/public <Directory /somewhere/public> # This relaxes Apache security settings. AllowOverride all # MultiViews must be turned off. Options -MultiViews # Uncomment this if you're on Apache >= 2.4: #Require all granted </Directory> </VirtualHost>
無事、Apacheモジュールも作成できた。DigitalOcean上に構築した/opt/rbenvを丸々haphostのVPSにコピーしました。
コピーしたRuby(rbenv)が利用可能であるか確認してみます。(以降はすべてhaphost上のVPSサーバでの実行例です)
$ . /opt/rbenv/.bash_profile $ which ruby /opt/rbenv/shims/ruby $ ruby -v ruby 2.2.0p0 (2014-12-25 revision 49005) [i686-linux]
ちゃんと動きました。
Sinatraアプリを配置
サンプルとして、「Hello Sinatra!」と表示するだけのアプリを公開してみます。このアプリ用にruby-hellosinatraユーザを作成し、/opt/webapps/ruby-hellosinatraに配置します。
ディレクトリと、ユーザを作成します。
$ sudo mkdir -p /opt/webapps/ruby-hellosinatra/public $ sudo useradd -u 2001 -g 2000 -d /opt/webapps/ruby-hellosinatra -s /bin/bash ruby-hellosinatra $ sudo chown -R ruby-hellosinatra:rbenv /opt/webapps/ruby-hellosinatra
/opt/webapps/ruby-hellosinatra配下にアプリを構成する、Gemfile、app.rb、config.ruを置きました。
$ ls -l total 16 -rw-r--r-- 1 ruby-hellosinatra rbenv 44 Jan 21 21:57 Gemfile -rw-r--r-- 1 ruby-hellosinatra rbenv 53 Jan 21 21:53 app.rb -rw-r--r-- 1 ruby-hellosinatra rbenv 83 Jan 21 21:55 config.ru drwxr-xr-x 2 ruby-hellosinatra rbenv 4096 Jan 21 21:46 public $ cat Gemfile source 'https://rubygems.org' gem 'sinatra' $ cat app.rb require 'sinatra' get '/' do "Hello Sinatra!" end $ cat config.ru require File.expand_path(File.dirname(__FILE__)) + '/app' run Sinatra::Application
bundleコマンドでGemfileからsinatraをインストールします。インストール先は、/opt/webapps/ruby-hellosinatra/vender/bundle です。
$ sudo su - ruby-hellosinatra ruby-hellosinatra@haphost:~$ . /opt/rbenv/.bash_profile ruby-hellosinatra@haphost:~$ pwd /opt/webapps/ruby-hellosinatra ruby-hellosinatra@haphost:~$ bundle install --path vender/bundle Fetching gem metadata from <a href="https://rubygems.org/...........">https://rubygems.org/...........</a> Resolving dependencies... Installing rack 1.6.0 Installing rack-protection 1.5.3 Installing tilt 1.4.1 Installing sinatra 1.4.5 Using bundler 1.7.11 Your bundle is complete! It was installed into ./vender/bundle ruby-hellosinatra@haphost:~$ ls -l vender/bundle/ruby/2.2.0/gems/ total 16 drwxr-xr-x 7 ruby-hellosinatra rbenv 4096 Jan 21 22:04 rack-1.6.0 drwxr-xr-x 4 ruby-hellosinatra rbenv 4096 Jan 21 22:04 rack-protection-1.5.3 drwxr-xr-x 5 ruby-hellosinatra rbenv 4096 Jan 21 22:04 sinatra-1.4.5 drwxr-xr-x 5 ruby-hellosinatra rbenv 4096 Jan 21 22:04 tilt-1.4.1
依存関係からrack、rack-protection、tilt、bundlerと4つのパッケージがインストールされました。一応アプリの起動までは確認しておきます。
ruby-hellosinatra@haphost:~$ bundle exec rackup -E prodution [2015-01-21 22:06:02] INFO WEBrick 1.3.1 [2015-01-21 22:06:02] INFO ruby 2.2.0 (2014-12-25) [i686-linux] [2015-01-21 22:06:02] INFO WEBrick::HTTPServer#start: pid=2118 port=9292 ^C[2015-01-21 22:06:11] INFO going to shutdown ... [2015-01-21 22:06:11] INFO WEBrick::HTTPServer#start done. ruby-hellosinatra@haphost:~$
sinatraを使った(Web)アプリが起動することを確認できました。
SinatraアプリとApacheの連携
haphostのVPSサーバにはhaphost.motop3j.netという名前をつけています。このhaphost.motop3j.netにバーチャルホストhellosinatra.motop3j.netを追加します。hellosinatra.motop3j.net名でApacheにリクエストが来た場合に限り、先ほど配置したアプリを公開するようにします。
Apacheはpassenger経由でsinatraアプリを起動することになります。DigitalOceanでコンパイルしたpassengerのapacheモジュールをApache側でロードしなければなりません。 /etc/apache2/mods-available配下にpassengerの設定ファイル2つを配置し、a2enmodコマンドでApacheでのモジュールロードを有効にします。
$ cat /etc/apache2/mods-available/passenger.load LoadModule passenger_module /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/passenger-4.0.57/buildout/apache2/mod_passenger.so $ cat /etc/apache2/mods-available/passenger.conf <IfModule mod_passenger.c> PassengerRoot /opt/rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/passenger-4.0.57 PassengerDefaultRuby /opt/rbenv/versions/2.2.0/bin/ruby </IfModule> $ sudo a2enmod passenger
続いて、バーチャルホストの設定です。Sinatraアプリ(hellosinatra)用サイトの設定フィアルを配置し、a2ensiteコマンドで有効にします。
$ cat /etc/apache2/sites-available/001-ruby-hellosinatra.conf <VirtualHost *:80> ServerName hellosinatra.motop3j.net ServerAdmin webmaster@localhost DocumentRoot /opt/webapps/ruby-hellosinatra/public RackEnv production CustomLog ${APACHE_LOG_DIR}/ruby-hellosinatra-access.log combined <Directory /opt/webapps/ruby-hellosinatra/src/public> #Require all granted Allow from all Options -MultiViews </Directory> </VirtualHost> $ sudo a2ensite 001-ruby-hellosinatra.conf
以上で、ApacheとSinatraアプリ(hellosinatra)連携の設定は完了です。Apacheに設定を反映させます。
$ sudo service apache2 reload
ブラウザで、http://hellosinatra.motop3j.netにアクセスしてみます。
hellosinatraが公開できていることが確認できました。
まとめ
前回に引続き、haphostでのVPSサーバの設定についてのエントリーを書きました。haphostをターゲットにしていますが、実際にはDebian7上でSinatraアプリを動かすまでの設定を行っただけです。他のVPSサービスでも、同じような手順でアプリを公開できるはずです。
2015年1月時点では、同じ手順でOreoreCA.もhaphostに移行しました。無事、DigitalOceanのインスタンスを停止することができました。100円をケチるつもりでしたが良く考えれば600円というか$5の節約です。。。全然工数には見合いませんが、定期的に環境を移行することは構築手順の整理にもなるし有益です。
移行したばっかりなんですが、実はついに先日(2015/01/14)DigitalOceanでFreeBSDのインスタンスが作成可能になりました。アプリ毎に実行環境をJailで分けたり、夢は広がります。余裕があれば近日中にDigitalOceanに戻るかもしれません。
ということで、しつこいようですがDigitalOceanへの登録はこちらから是非。