XserverVPSでRailsアプリを作成して動かす【Nginx/Unicorn/MySQL】

XserverVPSでRailsアプリケーション作りたいんだけどできる?
もちろんできるよ。

この記事ではXserverVPSでRailsアプリケーションを公開する方法を書いていきたいと思います。

記事の内容
  • XserverVPSでサーバーを立てる
  • XserverVPSでRailsアプリケーションを作成する
  • ローカルで作成したRailsアプリケーションをXserverVPSに公開する

これからXserverVPSでRailsアプリケーションを公開してみたい方は参考にしてみてください。UbuntuのサーバーにRubyやRailsを入れて環境を作っていきます。

XserverVPSでRailsアプリ公開していこう。

XserverVPSでサーバーを立てる

まずはXserver VPSでサーバーを立てます。申し込みの際には「VPSのお申し込み」を選択して必要な項目を選択していきます。

  • サーバー名・・・管理画面に表示されるサーバー名(自分で決めることも可能)
  • プラン・・・メモリの選択(試すなら2GBプランがお勧め)
  • サーバーの契約期間・・・サーバーの契約期間(12ヶ月がお勧め)
  • イメージタイプ・・・OSやアプリケーションの選択(アプリケーションの場合は選択したアプリケーションが使える環境を作ってくれる)
  • rootパスワード・・・rootユーザーのパスワード
  • SSH Key・・・SSH Keyを作成するかどうか

秘密鍵を作成した場合は、ダウンロード画面が表示されるので秘密鍵をダウンロードしましょう。

後は支払い画面に従って進んでいけばOKです。支払いが済むとトップページのサーバーに申し込んだものが表示されます。

サーバーにSSH接続する

ダウンロードした秘密鍵を.sshディレクトリに移動してパーミッションを変更します。

// .sshディレクトリに移動 
$ mv /Users/〇〇/Downloads/xserver-vps-ssh-key.pem /Users/〇〇/.ssh

// パーミッション変更
$ cd /Users/〇〇/.ssh
$ chmod 400 xserver-vps-ssh-key.pem

IPアドレスを確認する

SSH接続の際にはIPアドレスが必要なので、VPSパネルから確認します。

SSH接続する

SSHコマンドで接続してやりましょう。

$ ssh -i /Users/U/.ssh/xserver-secretkey.pem root@ipアドレス

接続するとroot@・・・という表示になりますね。

これでSSH接続はできたので、Railsに必要なものをインストールしていきます。

作業用のユーザーを作成する

rootユーザーで作業したくないので、作業用のユーザーを別に作ります。

# ユーザー作成
$ sudo adduser kobayashi

# 権限付与
$ sudo usermod -aG sudo kobayashi

# 鍵の設定
$ sudo rsync --archive --chown=kobayashi:kobayashi ~/.ssh /home/kobayashi

ユーザーを作成したら、再度作成したユーザーでSSH接続してみましょう。

Rubyをインストールする

作成したユーザーで再度SSH接続したらRubyをインストールします。rbenv経由でやっていきましょう。

# パッケージを最新に
$ sudo apt update
$ sudo apt upgrade

# 諸々入れる
$ sudo apt install make gcc libssl-dev zlib1g-dev

# rbenv
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ cd ~/.rbenv && src/configure && make -C src
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init - bash)"' >> ~/.bashrc
$ source ~/.bashrc

# ruby-build
$ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
# 設定内容確認
$ curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-doctor | bash

# rubyインストール
$ rbenv install --list
$ rbenv install 3.1.4
$ rbenv global 3.1.4

インストールしたらバージョン確認してみましょう。

$ ruby -v
ruby 3.1.4p223 (2023-03-30 revision 957bb7cb81) [x86_64-linux]

Railsインストール

続いてRailsのインストールを行います。

$ gem install bundler
$ gem install nokogiri -- --use-system-libraries
$ gem install rails --version="~>7.0"

インストールしたら確認してみましょう。

$ rails -v
Rails 7.0.4.3

Nginxをインストール

WebさーばーにはNginxを使うことにします。

# nginxをインストール
$ sudo apt install nginx

# nginxステータスの確認(ActiveだったらOK)
$ systemctl status nginx

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset:>
     Active: active (running) since Fri 2022-12-02 07:25:34 JST; 8s ago
       Docs: man:nginx(8)

インストールしたらブラウザにIPアドレスを入力して画面が表示されるか確認してみましょう。

MySQLをインストールする

データベースにはMySQLを使いたいのでインストールして起動しておきましょう。

# mysqlインストール
$ apt install mysql-server

# 起動
$ service mysql start

rootユーザーのパスワード変更

mysqlのrootユーザーのパスワードを設定します。

$ mysql -u root -p
Enterでログインできます。

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '<パスワード>';
mysql> FLUSH PRIVILEGES;

rootは基本使いたくないので、別のユーザーを作成します。

ユーザーの作成

mysql> CREATE USER 'ユーザー名'@'localhost' IDENTIFIED BY 'パスワード';
mysql> GRANT ALL PRIVILEGES ON * . * TO 'ユーザー名'@'localhost';
mysql> FLUSH PRIVILEGES;

これで作成したユーザーでデータベースの操作なんかも行うようにします。権限はGRANT ALLしているけど、適宜良い感じに設定しましょう。

データベースの作成

Railsアプリケーションから使うデータベースを作成します。

$ create database 〇〇;

Railsアプリケーションの作成

今回はRailsアプリケーションをサーバー上で作成してやります。作成するディレクトリはユーザーのホームディレクトリで行うことにしよう。

$ cd 
$ rails new rails_app -d mysql

mysql2が入らなかったので、以下コマンドで必要なものを入れました。

sudo apt-get install default-libmysqlclient-dev

トップページにアクセスがあった際のルーティングを設定する

デフォルトでは何も書かれていないので、コントローラーを作ってルーティングの記述をします。

$ rails g controller top
class TopController < ApplicationController
  def index
  end
end

config/routes.rbにはtopコントローラーのindexを参照するようにします。

Rails.application.routes.draw do
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  # Defines the root path route ("/")
  root "top#index"
end

views/top/index.html.erbにはHello World!!を表示するように記述。

Hello World!!

これでトップページにアクセスがあった際にはHello World!!が表示されるようになりました。

Unicornの設定

アプリケーションサーバーにはUnicornを使います。gemfileにunicornを記述してbundle install。

gem "unicorn"
$ bundle install

Unicornの設定ファイルも作っておきましょう。listenとpidのパスは自分の作成したアプリケーションのパスにしておきます。

$ vim /home/ユーザー名/rails_app/config/unicorn.rb
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true

listen '/home/ユーザー名/rails_app/tmp/unicorn.sock'
pid    '/home/ユーザー名/rails_app/tmp/unicorn.pid'

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])

続いてUnicornの起動や再起動などのコマンドを記したファイルも作っておきます。

$ vim /home/ユーザー名/rails_app/lib/tasks/unicorn.rake
namespace :unicorn do

  # Tasks
  desc "Start unicorn"
  task(:start) {
    config = Rails.root.join('config', 'unicorn.rb')
    sh "unicorn -c #{config} -E production -D"
  }

  desc "Stop unicorn"
  task(:stop) {
    unicorn_signal :QUIT
  }

  desc "Restart unicorn with USR2"
  task(:restart) {
    unicorn_signal :USR2
  }

  desc "Increment number of worker processes"
  task(:increment) {
    unicorn_signal :TTIN
  }

  desc "Decrement number of worker processes"
  task(:decrement) {
    unicorn_signal :TTOU
  }

  desc "Unicorn pstree (depends on pstree command)"
  task(:pstree) do
    sh "pstree '#{unicorn_pid}'"
  end

  # Helpers
  def unicorn_signal signal
    Process.kill signal, unicorn_pid
  end

  def unicorn_pid
    begin
      File.read("/home/ユーザー名/rails_app/tmp/unicorn.pid").to_i
    rescue Errno::ENOENT
      raise "Unicorn does not seem to be running"
    end
  end

end

Unicorn_pidのFile.read()も自分の配置したアプリケーションパスに合うようにします。

これでコマンドを実行するとUnicornが起動するはず。

$ rake unicorn:start

unicornのプロセスを確認してみるとちゃんと動いていますね。

$ ps -ef | grep unicorn | grep -v grep
kobayas+   75155       1  0 11:55 ?        00:00:01 unicorn master -c /home/kobayashi/rails_app/config/unicorn.rb -E production -D
kobayas+   75157   75155  0 11:55 ?        00:00:00 unicorn worker[0] -c /home/kobayashi/rails_app/config/unicorn.rb -E production -D
kobayas+   75159   75155  0 11:55 ?        00:00:00 unicorn worker[1] -c /home/kobayashi/rails_app/config/unicorn.rb -E production -D
kobayas+   75160   75155  0 11:55 ?        00:00:00 unicorn worker[2] -c /home/kobayashi/rails_app/config/unicorn.rb -E production -D

Nginxの設定を行う

NginxからはUnicornを参照したいので設定ファイルを作って記述します。serverのパスとserver_nameのIPアドレスは自分の環境に合わせたものにしましょう。

$ vim /etc/nginx/conf.d/rails_app.conf
upstream unicorn {
    server  unix:/home/ユーザー名/rails_app/tmp/unicorn.sock;
}

server {
    listen       80;
    server_name  IPアドレス;

    access_log  /var/log/nginx/access.log;
    error_log   /var/log/nginx/error.log;

    root /home/ubuntu/rails-todo/public;

    client_max_body_size 100m;
    error_page  404              /404.html;
    error_page  500 502 503 504  /500.html;
    try_files   $uri/index.html $uri @unicorn;

    location @unicorn {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_pass http://unicorn;
    }
}

NginxとUnicornの実行ユーザーを合わせる

NginxとUnicornの実行ユーザーが合っていないとエラーが起きるので確認しておきます。

$ ps -eaf | grep nginx
root       75270       1  0 12:05 ?        00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data   75271   75270  0 12:05 ?        00:00:00 nginx: worker process
www-data   75272   75270  0 12:05 ?        00:00:00 nginx: worker process
www-data   75273   75270  0 12:05 ?        00:00:00 nginx: worker process
kobayas+   75275   53059  0 12:05 pts/0    00:00:00 grep --color=auto nginx

$ ps aux | grep unicorn
kobayas+   75155  0.2  5.8 251820 117256 ?       Sl   11:55   0:01 unicorn master -c /home/kobayashi/rails_app/config/unicorn.rb -E production -D
kobayas+   75157  0.0  5.3 251820 108728 ?       Sl   11:55   0:00 unicorn worker[0] -c /home/kobayashi/rails_app/config/unicorn.rb -E production -D
kobayas+   75159  0.0  5.4 251820 109140 ?       Sl   11:55   0:00 unicorn worker[1] -c /home/kobayashi/rails_app/config/unicorn.rb -E production -D
kobayas+   75160  0.0  5.4 251820 109092 ?       Sl   11:55   0:00 unicorn worker[2] -c /home/kobayashi/rails_app/config/unicorn.rb -E production -D
kobayas+   75277  0.0  0.1   7536  2208 pts/0    S+   12:05   0:00 grep --color=auto unicorn

Nginxの場合はwww-dataがユーザーとして設定されていますが、unicornは自分が作成したユーザーになっていますね。Nginxも自分が作成したユーザーを設定します。

$ sudo vim /etc/nginx/nginx.conf
#user www-data;
user ユーザー名;

再起動しておきましょう。

$ sudo systemctl restart nginx

ブラウザからアクセスする

NginxとUnicornは設定できたもののブラウザからアクセスしてもまだ表示できないと思います。設定していきましょう。

Precompileする

$ RAILS_ENV=production bundle exec rails assets:precompile

エラー:ActionController::RoutingError (No route matches [GET] "/"):

ルーティングを記述しているのに上記のエラーが起きてしまいました。config/environments/production.rbの以下の記述を変更します。

# config.public_file_server_enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
config.public_file_server_enabled = true

これでunicornのpidファイルを一度消して再度起動したら動きました。

これでXserver VPSで立てたサーバーでRailsアプリケーションを動かすことができました。