0
0

More than 3 years have passed since last update.

Apache2 + Passenger + Sinatra でREST APIを構築する。

Last updated at Posted at 2020-09-03

REST API構築方針

すでにApache2でメインサービスを運用しているので、REST APIのためにネットワーク設定を変更したくない。ということでApache2でSinatraを動かす。万が一性能面で問題があったらFFI越しにRustの関数を呼び出すつもり。
Sinatraは、Apache2が公開しているメインアプリと並列にREST APIを公開する。以下の形で呼び出せるようにする。

http://localhost:8080/main_app
http://localhost:8080/sinatra

参考資料

  1. Installing Passenger + Apache on Ubuntu 18.04 LTS (with APT)
  2. Deploying an app to a sub-URI or subdirectory
  3. その他、同様の挑戦を行われた方々の記事(感謝!)

基本的なインストール

Vagrantで実験環境を構築する。インストール物は以下の通り。
1. Apache2
2. Ruby
3. bundler
4. Sinatra
5. sinatra-contrib
6. Passenger

メモリ1024MBでも動作するなら、本番サーバでの作業負荷も軽いはず。
vagrant sshするとエラーになることがあるので、インストール最初にsshの設定を行っている。

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/bionic64"

  config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

  config.vm.synced_folder "./data", "/vagrant_data"

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
  end

  config.vm.provision "shell", inline: <<-SHELL
    # To solve the issue of "vagrant@127.0.0.1: permission denied (publickey)."
    sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config; \
    sudo systemctl restart sshd;

    apt-get update
    # Installing Apache2
    apt-get install -y apache2

    # Installing Ruby & sinatra
    apt-get install -y ruby
    gem install bundler
    gem install sinatra
    gem install sinatra-contrib

    # [Installing Passenger + Apache on Ubuntu 18.04 LTS (with APT)]
    # (https://www.phusionpassenger.com/library/install/apache/install/oss/bionic/)
    sudo apt-get install -y dirmngr gnupg
    sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
    sudo apt-get install -y apt-transport-https ca-certificates

    sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list'
    sudo apt-get update

    sudo apt-get install -y libapache2-mod-passenger

    sudo a2enmod passenger
    sudo a2enmod headers
    sudo apache2ctl restart
  SHELL
end

インストール物バージョン確認

vagrant sshでログインして確認する。パスワードはvagrant

Apache2

Apache2のバージョンによって、Apache2の設定(Require all granted)を書くかどうかが決まる。

$ apache2 -v
Server version: Apache/2.4.29 (Ubuntu)
Server built:   2020-08-12T21:33:25

Ruby

Rubyのバージョンは、ここでは普通に使えることの確認も込めて行っている。

$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]

Rubyの実行ファイルの場所をApache2の設定(PassengerRuby /usr/bin/ruby2.5)に反映することになる。

Ruby Gems (bundler,sinatra,sinatra-contrib)

ここまでの作業でインストールされていたのは以下の通り。

$gem list
backports (3.18.2)
bigdecimal (default: 1.3.4)
bundler (2.1.4)
cmath (default: 1.0.0)
csv (default: 1.0.0)
date (default: 1.0.0)
dbm (default: 1.0.0)
did_you_mean (1.2.0)
etc (default: 1.0.0)
fcntl (default: 1.0.0)
fiddle (default: 1.0.0)
fileutils (default: 1.0.2)
gdbm (default: 2.0.0)
io-console (default: 0.4.6)
ipaddr (default: 1.2.0)
json (default: 2.1.0)
minitest (5.10.3)
multi_json (1.15.0)
mustermann (1.1.1)
net-telnet (0.1.1)
openssl (default: 2.1.1)
power_assert (0.2.7)
psych (default: 3.0.2)
rack (2.2.3, 1.6.4)
rack-protection (2.0.8.1)
rake (12.3.1)
rdoc (default: 6.0.1)
ruby2_keywords (0.0.2)
scanf (default: 1.0.0)
sdbm (default: 1.0.0)
sinatra (2.0.8.1)
sinatra-contrib (2.0.8.1)
stringio (default: 0.0.1)
strscan (default: 1.0.0)
test-unit (3.2.5)
tilt (2.0.10)
webrick (default: 1.4.2)
zlib (default: 1.0.0)

Passenger

Step 3: check installationを参考に、動作確認を行う。

$ sudo /usr/bin/passenger-config validate-install
What would you like to validate?
Use <space> to select.
If the menu doesn't display correctly, press '!'

 . ●  Passenger itself
   ○  Apache

-------------------------------------------------------------------------

 * Checking whether this Passenger install is in PATH... ✓
 * Checking whether there are no other Passenger installations... ✓

Everything looks good. :-)

Apacheをチェックしても認識されない。PassengerからApache2を認識する必要はないので問題ない。

メモリ使用状況を確認する。

$ sudo /usr/sbin/passenger-memory-stats
Version: 6.0.6
Date   : 2020-09-03 00:07:00 +0000

--------- Apache processes ----------
PID   PPID  VMSize     Private  Name
-------------------------------------
4238  1     153.9 MB   0.5 MB   /usr/sbin/apache2 -k start
4483  4238  1268.4 MB  0.7 MB   /usr/sbin/apache2 -k start
4484  4238  1268.4 MB  0.6 MB   /usr/sbin/apache2 -k start
### Processes: 3
### Total private dirty RSS: 1.78 MB


-------- Nginx processes --------

### Processes: 0
### Total private dirty RSS: 0.00 MB


---- Passenger processes -----
PID   VMSize    Private  Name
------------------------------
4468  389.7 MB  2.3 MB   Passenger watchdog
4471  946.3 MB  3.4 MB   Passenger core
### Processes: 2
### Total private dirty RSS: 5.64 MB

PassengerがRubyを認識しているかを確認する。Determine the Ruby command that Passenger should useを参考にする。

$ passenger-config about ruby-command
passenger-config was invoked through the following Ruby interpreter:
  Command: /usr/bin/ruby2.5
  Version: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
  To use in Apache: PassengerRuby /usr/bin/ruby2.5
  To use in Nginx : passenger_ruby /usr/bin/ruby2.5
  To use with Standalone: /usr/bin/ruby2.5 /usr/bin/passenger start

The following Ruby interpreter was found first in $PATH:
  Command: /usr/bin/ruby
  Version: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
  To use in Apache: PassengerRuby /usr/bin/ruby
  To use in Nginx : passenger_ruby /usr/bin/ruby
  To use with Standalone: /usr/bin/ruby /usr/bin/passenger start

## Notes for RVM users
Do you want to know which command to use for a different Ruby interpreter? 'rvm use' that Ruby interpreter, then re-run 'passenger-config about ruby-command'.

/usr/bin/ruby2.5はApache2に設定するので覚えておく。

Sinatraアプリケーション構成

SinatraアプリをApache2+Passenger構成で動作させるには、アプリケーション構成上の注意がある。アプリケーションのディレクトリにpublic、tmpのディレクトリが必要になる。中身は空でよい。

/home/vagrant/sinatra$ $ ls -al
total 32
drwxr-xr-x 4 vagrant vagrant 4096 Sep  3 00:59 .
drwxr-xr-x 7 vagrant vagrant 4096 Sep  3 00:46 ..
-rw-r--r-- 1 vagrant vagrant   79 Sep  3 00:50 Gemfile
-rw-r--r-- 1 vagrant vagrant   83 Sep  3 00:59 app.rb
-rw-r--r-- 1 vagrant vagrant   63 Sep  3 00:31 config.ru
drwxr-xr-x 2 vagrant vagrant 4096 Sep  3 00:31 public
drwxr-xr-x 2 vagrant vagrant 4096 Sep  3 00:31 tmp
/home/vagrant/sinatra/Gemfile
source 'https://rubygems.org/'

gem 'sinatra'
gem 'sinatra-contrib'
gem 'rack'
/home/vagrant/sinatra/app.rb
Bundler.require

  get '/' do
    "I did it my way"
  end
/home/vagrant/sinatra/config.ru
require File.absolute_path("app.rb")

run Sinatra::Application

bundlerを実行し、アプリケーションの依存関係を設定する。

~/sinatra$ bundler install
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Using backports 3.18.2
Following files may not be writable, so sudo is needed:
  /usr/local/bin
  /var/lib/gems/2.5.0
  /var/lib/gems/2.5.0/build_info
  /var/lib/gems/2.5.0/cache
  /var/lib/gems/2.5.0/doc
  /var/lib/gems/2.5.0/extensions
  /var/lib/gems/2.5.0/gems
  /var/lib/gems/2.5.0/specifications
Using bundler 2.1.4
Using multi_json 1.15.0
Using ruby2_keywords 0.0.2
Using mustermann 1.1.1
Using rack 2.2.3
Using rack-protection 2.0.8.1
Using tilt 2.0.10
Using sinatra 2.0.8.1
Using sinatra-contrib 2.0.8.1
Bundle complete! 3 Gemfile dependencies, 10 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

Gemfile.lockができていればOK。

/home/vagrant/sinatra/Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:
    backports (3.18.2)
    multi_json (1.15.0)
    mustermann (1.1.1)
      ruby2_keywords (~> 0.0.1)
    rack (2.2.3)
    rack-protection (2.0.8.1)
      rack
    ruby2_keywords (0.0.2)
    sinatra (2.0.8.1)
      mustermann (~> 1.0)
      rack (~> 2.0)
      rack-protection (= 2.0.8.1)
      tilt (~> 2.0)
    sinatra-contrib (2.0.8.1)
      backports (>= 2.8.2)
      multi_json
      mustermann (~> 1.0)
      rack-protection (= 2.0.8.1)
      sinatra (= 2.0.8.1)
      tilt (~> 2.0)
    tilt (2.0.10)

PLATFORMS
  ruby

DEPENDENCIES
  rack
  sinatra
  sinatra-contrib

BUNDLED WITH
   2.1.4

Apache2が認識するディレクトリをリンクする。

$ sudo ln -s /home/vagrant/sinatra sinatra
$ ls -l
total 4
drwxr-xr-x 2 root root 4096 Sep  2 23:30 html
lrwxrwxrwx 1 root root   21 Sep  3 00:35 sinatra -> /home/vagrant/sinatra

/etc/apache2/mods-available/passenger.confの設定

Deploying an app to a sub-URI or subdirectoryを参考に、設定ファイルを編集する。
### Beginから### Endまでは、Passengerのインストールの際に記述されているので、そのあとの設定を追記する。設定項目はPassengerのバージョンによって違ってくるので、バージョンの違うPassengerを使う際は注意。
PassengerRubyに、rubyの実行ファイルの場所を指定する。
Apache2のバージョンが2.4以上の場合、Require all grantedを記述する。
ひとつだけ、RackBaseURIと書く場所があるのだが、これが正しい。

/etc/apache2/mods-available/passenger.conf
### Begin automatically installed Phusion Passenger config snippet ###
<IfModule mod_passenger.c>
  PassengerRoot /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini
  PassengerDefaultRuby /usr/bin/passenger_free_ruby
</IfModule>
### End automatically installed Phusion Passenger config snippet ###

PassengerRuby /usr/bin/ruby2.5
RackBaseURI /sinatra

Alias /sinatra /var/www/sinatra/public
<Location /sinatra>
  PassengerBaseURI /sinatra
  PassengerAppRoot /var/www/sinatra
</Location>
<Directory /var/www/sinatra/public>
  Allow from all
  Options -MultiViews
  Require all granted
</Directory>

Apache2再起動

$ sudo service apache2 restart

念のため、状態を確認する。

$ sudo service apache2 status
● apache2.service - The Apache HTTP Server
   Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
  Drop-In: /lib/systemd/system/apache2.service.d
           └─apache2-systemd.conf
   Active: active (running) since Thu 2020-09-03 00:25:40 UTC; 47s ago
  Process: 4811 ExecStop=/usr/sbin/apachectl stop (code=exited, status=0/SUCCESS)
  Process: 4817 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
 Main PID: 2595 (code=exited, status=0/SUCCESS)
    Tasks: 73 (limit: 1152)
   CGroup: /system.slice/apache2.service
           ├─4871 /usr/sbin/apache2 -k start
           ├─4874 Passenger watchdog
           ├─4878 Passenger core
           ├─4892 /usr/sbin/apache2 -k start
           └─4893 /usr/sbin/apache2 -k start

Sep 03 00:25:40 ubuntu-bionic systemd[1]: Starting The Apache HTTP Server...
Sep 03 00:25:40 ubuntu-bionic apachectl[4817]: AH00558: apache2: Could not reliably determine the server's fully qualified d
Sep 03 00:25:40 ubuntu-bionic systemd[1]: Started The Apache HTTP Server.

Passengerも起動している。

動作確認

まずはメインアプリ。
20200903_main_app.png

Sinatraの動作確認。
20200903_sinatra_1.png

うまくいかないときは、エラー画面がでる。
20200903_error.png

Passengerのエラー画面すら出ないときは、そもそもPassengerまでたどり着いていない。Apache2自体の設定ミスの可能性がある。エラーが出た時は、/var/log/apache2/error.logを確認する。

課題

勉強不足により、解決していない項目は以下の通り。

  1. Bundlerを分かってない。gem install sinatraしなくていいのでは。
  2. Sinatraがauto reloadしない。Gemfileに'sinatra-contrib'を書いただけではダメか。
  3. Sinatraアプリの配置。公開サービスのセキュリティは慎重に。
  4. Sinatraアプリの認証処理。
  5. Sinatra(Ruby)からFFI越しにRustの関数を呼ぶ方法。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0