14
12

More than 3 years have passed since last update.

Raspberry Pi をサーバとしてRailsのアプリケーションをデプロイするまで

Last updated at Posted at 2019-11-15

概要

開発中のRailsアプリケーションを実際に自分でも使いたいので、できるだけ金をかけずにデプロイする方法を考えた。URLとかドメインとかの個人的なこだわりとアプリケーションの使用環境を考えるとHerokuはやなので、Apache&Passengerのコンボで以前購入したRaspberry Piをサーバーとして、アプリケーションをデプロイしてみる。作業が色々回りくどかったことと、あまり包括的にラズパイでのサーバー構築に関してカバーしてる記事がなかったので備忘として残しておくことに。
自分も初めてやったし独学なので、今後のために極力わかりやすく丁寧に書く。
*セキュリティは現段階では(おそらく)貧弱なので自己責任でお願いします。ご指摘いただけると幸いです。
*各ステップにおける説明の加減は自分の理解度が低いところに優先的に比重をかけています。

前提

使用するのは主に、
- Raspberry Pi
- Filezilla (Piへのファイル転送用)
- Apache
- Passenger
- Ruby&Rails (Ruby 2.6.0, Rails 5.2.3)
- ドメインと転送設定他

Raspberry Piは、以前トライしてみたHeadlessインストール(ディスプレイなしでのインストール)で要素が増えすぎて大変だったので、Noob経由でRaspbian Liteをインストール。sshを有効にした状態からスタート。操作はMacbookからsshで行う。
ApachePassengerはこれから導入していく。
RubyとRailsもこれからインストール。すでに作成したアプリケーションがあるのでそれをデプロイする。
ドメインは、フリードメインを入手してある(.tk)。Piが繋がってるルーターで転送設定して、かつドメインからDNSでルータに繋がるように設定済み。

ドメインのところは、それはそれで初心者にはややこしい。また機会があれば書くけれど、今回は面倒なので割愛。特にドメインとかいらないよって場合は、この記事ではドメインをpublic IPで置き換えて入れればだいたいうまくいくはず。というかそちらの方が要素が少ないので確実。

目標

最終的に、ブラウザーで専用のドメインのURLを入力して、アプリケーションのトップページが表示されれば成功。

流れ

全体的な流れは以下のように進めます。
0. スタート地点の確認
1. RubyとRailsをインストール
2. Apacheをインストール
3. Passengerをインストール
4. Testアプリで動作確認
5. アプリケーションの転送と設定
6. 最終確認

長くなりそう。
それでは早速。

0. スタート地点の確認

前提でも書きましたが、目標に照らしてさらっと現状を確認します。
現段階でブラウザにURL入れるとこんな感じ。
image.jpeg
当たり前。
当たり前すぎてある意味安心。

1. RubyとRailsをインストール

下準備として、まずRubyをPiに入れていきます。今回は2.6.0でいきます。

sshでpiにログイン

MacbookのTerminalからsshでPiにログインします。
ssh pi@YOUR_DOMAIN
piはRaspberry Piのユーザ名(デフォルトはpiです)、YOUR_DOMAINのところに自分のドメインか、転送設定をしたpublic IPを入れます。

バージョン管理のための下準備

アプリケーションによって使用するrubyのバージョンが異なる場合があるので、バージョン管理をするために使うrbenvを入れます。

まずはパッケージの更新。

pi
$ sudo apt-get update
$ sudo apt-get upgrade

gitを入れる。rbenv入れるのとかupdateに使います。

pi
sudo apt install git

nodejs (念のため)

pi
$ sudo apt-get install nodejs

rbenvインストール (バージョン管理用)

rbenv

pi
$ sudo git clone https://github.com/rbenv/rbenv.git ~/.rbenv

これでrbenvは入ったんですが、これをrbenv init ほにゃららで実行できるようにするため、俗にいう「pathを通す」ということをします。

pi
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc

.bashrcはbashが起動されるたびに実行される。>>は追記という意味なので、.bashrcにrbenv init -を追記することになる。.bassh_profileはログイン時のみなのでsshだとめんどくさそうということで、ここでは.bashrcにしておく。(sshでrapberry pi再起動した時は嫌な思い出しかない)

次。ruby-buildを入れておきます。rbenvでrubyをインストールするために必要です。~/.rbenv/plugingsに作成されます。

pi
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

最後にrehashする。

pi
$ sudo rbenv rehash

rbenvでは、バージョンごとに実行するファイルを分けるためにerb, gem, irb等ごとにフォルダを用意し、以下にバージョンごとのファイルを振り分けてくれます。shimと呼ばれるやつです。こうしておくことで、rbenv関連のコマンドが入ると、~/.rbenv/shimsを通して、バージョンに適切なファイルを実行できるようにしてあります。このshimsは、新しいgemなどを入れるたびに更新する必要があるため、それを行なっているのが上記のコマンド。

ここで念のため、一度MacbookのTerminalも閉じて、もう一度sshを接続し直します。

Rubyをインストール

まずはインストールできるバージョンを確認。上記でgitからrbenv/ruby-buildを入れているなら最新なはずです。

2.6.0があるか確認。

pi
$ rbenv install --list

Screen Shot 2019-07-12 at 10.37.48.jpeg
あった。よし。

今回は2.6.0を入れます。
2.4, 2.5あたり以前を入れる場合は注意。CPUとの相性がどうたらでPassengerでBus ErrorやSegmentation Fault Errorが出たりします。解決法はありますが、めんどいので2.6.0。解決法はここ(HatenaBlog)
時間かかるので注意。僕の場合は30分弱かかった。

pi
$ rbenv install 2.6.0
$ rbenv global 2.6.0 # 以降使用するバージョンを設定
$ rbenv rehash # 恒例のrehash

インストールできたか確認する。

pi
$ ruby --version
=> ruby 2.6.0p0 (2018-12-25 revision 66547) [armv7l-linux-eabihf]

バージョン情報が表示されたということは、入ってる。
よし。

Railsのインストール

導入

Railsを入れていきます。
まずパッケージ管理用のbundlerを入れます。

pi
$ gem install bundler

Railsを入れます。
これは僕の場合は15分くらいかかりました。

pi
$ gem install rails

動作確認。

pi
$ rails --version
=> Rails 5.2.3

おっけい。

2. Apacheをインストール

こちらは、Raspberry Pi公式でドキュメンテーションがあるのでそれに従います。(この記事では利用しませんが、index.htmlを変更して自分の簡単なwebサイトをApacheに表示させる方法も書いてあります。)

pi
$ sudo apt-get update
$ sudo apt-get install apache2 -y

-yは、--assume-yesの略で、promptに対して自動でyで回答するというもの。

Apache動作確認

ここまでうまくいって入れば、ブラウザでURLを入力すればApacheの初期画面が表示されるはず。
やってみる。
image.jpeg
やった...! (涙目

3. Passengerをインストール

次。ApacheでRailsアプリケーションを動かすために、ApacheのモジュールであるPhusion Passengerを入れます。インストールと初期設定(configuration)で少し量があるので見出し分けます。

インストール

まずはPassengerをgemでインストール。
5分ほどかかります。sudoは使わない。

pi
$ gem install passenger

次に、ApacheとPassengerを連帯させます。コマンドを入力するとインストラクションが表示されるので、従っていけば大丈夫です。しっかり読みながら進めます。

pi
$ passenger-install-apache2-module

いくつかEnterを押すと、自動でチェックを始める。
image.jpeg
チェックが終わると、必要なもののインストール方法を教えてくれる。
image.jpeg

従順に従って、すべてインストールします。
文頭にはsudoをつけて実行します。
僕の場合は、
- sudo apt-get install libcurl4-openssl-dev
- sudo apt-get install ruby-dev
- sudo apt-get install apache2-threaded-dev
- sudo apt-get install libapr1-dev
- sudo apt-get install libaprutil1-dev

やってみると、エラーが出た。

pi
$ sudo apt-get install apache2-threaded-dev
=> Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package apache2-threaded-dev

対処法は、こう書き換えて実行すること。原因は不明。
sudo apt-get install apache2-dev

全部終わったら、再度

pi
$ passenger-install-apache2-module

ここは20分以上かかりました。

備考:
仮にインストールしたはずなのにまた同じインストール要求をされる場合は、
sudo apt autoremove
を行なって、apache2-devのみ入れて、もう一度
passenger-install-apache2-module
を行なってみるとうまくいくかも。

終了すると以下のような表示が出ます。
image.jpeg

Apache configurationファイルを編集し、以下を追記してくださいという表示です。僕の場合はこのように出ています。

pi
   LoadModule passenger_module /home/pi/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/passenger-6.0.2/buildout/apache2/mod_passenger.so
   <IfModule mod_passenger.c>
     PassengerRoot /home/pi/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/passenger-6.0.2
     PassengerDefaultRuby /home/pi/.rbenv/versions/2.6.0/bin/ruby
   </IfModule>

これは環境によって変わる可能性があるので、ご自分のコンソールに表示されたものをコピーしておいてください。

初期設定 (configuration)

上記でコピーを取ったものをApacheのconfigurationファイルに追加します。

"Press ENTER when you are done editing."

とあるので、念のため別のsshセッションを開始してそこから編集します。

基本的にApacheのconfigurationファイルは、
/etc/apache2/
内にある、apache2.confです。

編集権限を持たせるためsudoでテキストエディタ(nano)を起動します。

pi
$ sudo nano /etc/apache2/apache2.conf

コピペ。
image.jpeg

ctr+xのちにY、そしてEnterを押すと保存してnanoを終了します。

1つめのsshに戻って、Enterを押すと、インストールが正しく行われたかチェックしてくれます。
image.jpeg
Everything looks good. :-)
を表示されればOk.

最後に念のため、PassengerとApache双方がうまく動いているか確認。

pi
$ sudo passenger-config validate-install

すると
image.jpeg

おっと、

pi
* Checking whether the Passenger module is correctly configured in Apache... ✗

Incorrect Passenger module path detected

   Phusion Passenger for Apache requires a 'LoadModule passenger_module'
   directive inside an Apache configuration file. This directive has been
   detected in the following config file:

      /etc/apache2/apache2.conf

   However, the directive refers to the following Apache module, which is wrong:

      /home/pi/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/passenger-6.0.2/buildout/apache2/mod_passenger.so

   Please edit the config file and change the directive to this instead:

      LoadModule passenger_module /var/lib/gems/2.5.0/gems/passenger-6.0.2/buildout/apache2/mod_passenger.so

configファイルは存在するけど、Apacheへのパスの設定が間違っている、と言っています。
ただ僕はrubyをrbenvで管理しており、rubyも2.6.0を入れたので、パスはあっていると判断。
続行します。

4. Testアプリで動作確認

Railsでテスト用のアプリを作成し、Passengerにそのファイルを参照させることで、URLにアクセスするとRuby on Railsの初期画面が表示されるところまで持っていきます。これで、Apache, Passenger, Railsが正しく動作することを確認。

TestアプリをRailsで作成

ただプロジェクトを作るだけです。
プロジェクトを作成するパスまでナビゲートし、rails用のフォルダを作成。

pi
$ cd /var/www/ 
$ sudo mkdir rails # rails用のフォルダ作成
$ sudo chmod -R 777 rails # permissionを設定 (注意!)
$ cd rails # 作ったフォルダに移動

3行目の sudo chmod -R 777 rails は、危険な方法です。
今回はRailsが必要なフォルダを作成するためにrailsフォルダの全ての権限を解放しています。しかし、これは今回の目的が実験的にRailsを動かすためであるからで、セキュリティ的には危険です。ウェブサイトとして公開した際、訪問者がrailsフォルダ内のデータをどうとでもできる状態です。本来はApacheのみに権限を与えることでRailsが必要な挙動を許可されるようにします。 参考1, 参考2

今回は個人的なテストなのでよしとして、ここで、Railsプロジェクトを作成。

pi
$ rails new TestApp --skip-bundle

--skip-bundleは、初期に自動でbundle installするのを飛ばします。古いバージョンのRailsでは、初期のbundle installが問題を起こすことがあったので念のため。

PassengerをTestAppに向ける

まず、使うrubyのパスを調べます。

pi
$ passenger-config about ruby-command
=> passenger-config was invoked through the following Ruby interpreter:

  Command: /home/pi/.rbenv/versions/2.6.0/bin/ruby # これがrubyのパス。

  Version: ruby 2.6.0p0 (2018-12-25 revision 66547) [armv7l-linux-eabihf]

ということで、/home/pi/.rbenv/versions/2.6.0/bin/rubyがrubyのパス。

次に、/etc/apache2/apache2.configを再度nanoで編集し、以下を追記します。

pi
<VirtualHost *:80>
    ServerName yourserver.com # 自分のドメイン

    # Tell Apache and Passenger where your app's 'public' directory is
    DocumentRoot /var/www/rails/TestApp/public # 先ほど作ったTestApp内の'public'というフォルダ

    PassengerRuby /home/pi/.rbenv/versions/2.6.0/bin/ruby # 今見つけたrubyへのパス。

    # Relax Apache security settings
    <Directory /var/www/rails/TestApp/public> # ここのパスも、先ほどと同じくTestAppのpublicフォルダ
      Allow from all
      Options -MultiViews
      # Uncomment this if you're on Apache > 2.4:
      #Require all granted
    </Directory>
</VirtualHost>

先ほどと同じように、ctr+xYEnterで保存してnanoを終了します。

できたら、Apacheを再起動します。

pi
$ sudo apachectl restart

ここまできたら、早速ブラウザからドメインにアクセスして見ましょう。

image.jpeg
なんでやねん。

まずは、ブラウザ上からエラーメッセージの詳細を確認できるように設定しましょう。
/etc/apache2/apache2.confに、

pi
PassengerFriendlyErrorPages on

と追記します。
VirtualHostタグの中に。
hide.jpg

Apacheを再起動。

pi
$ sudo apachectl restart

ブラウザを更新すると、
image.jpeg
よし、進歩。

わかった、bundleだ。

pi
$ cd /var/www/rails/TestApp
$ bundle install

更新。
image.jpeg
なんでやねん。

あ、わかった、RailsアプリがDevelopmentになってると、Passengerはアプリを起動してくれません。それを、Developmentモードでも大丈夫だよとPassengerに伝えるために、Apacheのコンフィギュレーションをいじります。

なので、/etc/apache2/apache2.confを再度編集し、RailsEnv developmentの記述を追加します。

pi
$ sudo nano /etc/apache2/apache2.conf

hide2.jpg

できたら、
sudo apachectl restartでApacheを再起動。

ブラウザを更新すると...

image.jpeg
これが見えた時の喜びのすごさよ。

5. アプリケーションの転送と設定

ただのRailsの画面では面白くないので、あらかじめ作成しておいたアプリをPiに転送して、それが動くか確かめて見る。

FileZillaで転送します。

Quick ConnectionでPiに接続後、アプリのフォルダを
/var/www/rails 内にドラッグドロップします。

転送が完了したら、apache2.confを編集。

僕の場合アプリ名(つまりフォルダ名)は
Daruma
なので、

/etc/apache2/apache2.confをnanoで編集し、VirtualHostの部分を以下のように編集します。

pi
<VirtualHost *:80>
    ServerName YOUR DOMAIN # ドメイン名またはIP
    # Tell Apache and Passenger where your app's 'public' directory is
    DocumentRoot /var/www/rails/Daruma/public # ← ここを変更。

    RailsEnv development
    PassengerRuby /home/pi/.rbenv/versions/2.6.0/bin/ruby
    PassengerFriendlyErrorPages on
    # Relax Apache security settings
    <Directory /var/www/rails/TestApp/public>
      Allow from all
      Options -MultiViews
      # Uncomment this if you're on Apache > 2.4:
      #Require all granted
    </Directory>
</VirtualHost>

できたら保存。

忘れずに、

pi
$ bundle install

6. 最終確認

ブラウザーを更新して、アプリのトップページが表示されるか確かめます。

image.jpeg
よっしゃ。
目標達成!!!

/

14
12
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
14
12