ConoHa VPS

ConoHa VPSでRailsアプリをデプロイする【CentOS9/Nginx/Unicorn/MySQL/Rails7.0.4】

ConoHa VPSでRailsアプリデプロイしたいんだけど?

今回はConoHa VPSでローカルで作成したRailsアプリを公開していきます。(とは言っても試行錯誤しつつ)

この記事でやること

  • ConoHa VPSでサーバーの作成
  • 作成したサーバーにローカルのRailsアプリをデプロイ

ConoHa VPSでRailsアプリケーションを公開してみたい人はどんなふうにできるのか、なんとなくイメージが湧くかもしれません。

テンプレートは使わない

以前Railsのテンプレートを使うっていうことをやったけど、今回テンプレートは使いません。

ConoHa VPS

ConoHa VPSでRail環境を簡単に作成する【テンプレート使用】

2022/12/5  

この記事ではConoHa VPSでRuby on Railsの環境を簡単に作るべく、テンプレートを使って作っていきたいと思います。 ConoHa VPSでRails環境が欲しかったら見てみてください。 ...

(テンプレート使ってやってみたらごちゃごちゃして結局途中で断念したので)

ConoHa VPSでRailsアプリを公開してみましょう。

公開するRailsアプリケーション

公開してみるのはなんのデザインもないTODOアプリです。

これをConoHa VPSに公開していきます。

ConoHa VPSでサーバーを立てる

まずはConoHa VPSでサーバーを立てます。OSはCentOSでいきます。ConoHa VPSから申し込むと700円のクーポンがもらえるみたいです。

自分はサーバーのOSを再インストールしてやりますが、新たに作成する場合は以下のような選択でやるといいでしょう。

  • サービス・・・VPS
  • VPS割引きっぷ・・・3ヶ月以上利用するなら使うのが安くなるのでおすすめ
  • メモリ・・・1GB以上にはしておこう
  • OS・・・CentOSかUbuntuあたりにしておけばいいかと
  • rootパスワード・・・rootのパスワード
  • ネームタグ・・・管理画面に表示されるサーバーの名前

オプションはいくつかあるので、何か追加したい項目があればやっておくといいです。SSH Keyぐらいはやっておくと楽です。

これで追加ボタンを押すとサーバーが作成されます。

SSH接続する

作業はSSH接続してサーバーの中でやりたいです。

$ ssh -i 秘密鍵へのパス root@IPアドレス

ConoHa VPS

ConoHa VPSでSSH接続する方法とおすすめ設定を紹介します。

2022/8/2  

今回はそんなConoHa VPSでSSH接続する方法を書いていきたいと思います。 SSH接続する方法を見ていくんですが、後半ではセキュリティ面を意識してrootユーザーではSSH接続できないようにして ...

ユーザーの作成

rootとは別にユーザーを作ります。

$ useradd kobayashi
$ passwd kobayashi

これで/home配下に作成したユーザーディレクトリが作成されているはずです。

[root@xxx-xx-xx-xxx home]# ls
kobayashi

CentOSにはwheelグループが最初から存在しているので、そこに作成したユーザーを追加します。今回はkobayashiを作成したのでkobayashiを追加。

# wheelグループに追加
$ usermod -aG wheel kobayashi

# wheelを有効にする
$ vi /etc/pam.d/su

# 以下のコメントアウトを外す
auth sufficient pam_wheel.so trust use_uid
auth required pam_wheel.so use_uid
作成したユーザーがwheelグループに入ったかどうかを確認します。

$ cat /etc/group | grep wheel
# 作成したユーザーが表示されていればOK

鍵を設置するディレクトリを作ってSSH接続できるように置いておきます。

$ su kobayashi
$ cd /home/kobayashi
$ mkdir .ssh
$ sudo cp /root/.ssh/authorized_keys /home/kobayashi/.ssh/.
$ chmod 700 .ssh
$ sudo chmod 600 .ssh/authorized_keys

# もし所有者とグループが違ったら作成したユーザーに直す
$ chown username:group .ssh
$ chown username:group .ssh/authorized_keys

作成したユーザーでSSH接続できればOK。

$ ssh -i 秘密鍵 kobayashi@IPアドレス
# パスワードが求められるので、設定したパスワードを入力

今回はこの作成したユーザーの配下にRailsアプリをアップロードしたいと思います。作業はこの作成したユーザーで行っていきます。

パッケージの更新

これから色々インストールしていくんですが、その前にパッケージの更新等はしておきます。

$ sudo dnf update
$ sudo dnf upgrade

Rubyをインストールする

Rubyをインストールしましょう。

rbenvをインストールする

$ sudo dnf install -y git
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ ~/.rbenv/bin/rbenv init
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l

$ rbenv -v
rbenv 1.2.0-48-g6717c62

ruby-buildをインストールする

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

rubyをインストールする

$ sudo dnf install -y gcc openssl-devel readline-devel zlib-devel
$ rbenv install -l
2.7.7
3.0.5
3.1.3
jruby-9.4.0.0
mruby-3.1.0
picoruby-3.0.0
rbx-5.0
truffleruby-22.3.0
truffleruby+graalvm-22.3.0

$ rbenv install 3.1.3
$ rbenv global 3.1.3
$ ruby -v
ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [x86_64-linux]

これでrubyがインストールされました。デプロイしたいアプリケーションで使っているrubyのバージョンをインストールするといいですよ。

Railsインストール

Railsも入れておきます。これもアプリケーションのバージョンと合わせます。

$ gem install rails -v 7.0.4
$ rails -v
Rails 7.0.4

Nginxのインストールと設定

WebサーバーにはNginxを使ってやります。

Nginxインストール

$ sudo dnf -y install nginx

# 起動
$ sudo systemctl start nginx

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

画面を確認したいところだけど、Firewallで弾かれるので設定します。

Firewall設定

firewallでhttpを許可します。

# ステータス確認
$ systemctl status firewalld.service

● firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor>
     Active: active (running) since Mon 2022-12-05 14:27:25 JST; 58min ago
$ sudo firewall-cmd --zone=public --add-service=http --permanent
$ sudo firewall-cmd --reload

これでservicesにhttpが追加されましたね。

$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: cockpit dhcpv6-client http ssh
  ports:

ブラウザから確認する

ブラウザにIPアドレスを入力すると画面が表示されました。

Nginxの設定ファイルも作りたいけど、後で作ります。

MySQLのインストール

データベースにはMySQLを使います。

$ sudo dnf -y install mysql
$ sudo dnf -y install mysql-server
$ mysqld --version
/usr/libexec/mysqld  Ver 8.0.30 for Linux on x86_64 (Source distribution)

起動しておきましょう。

$ sudo systemctl start mysqld
$ sudo systemctl status mysqld
=> ActiveならOK

少しだけ設定しておきましょう。

rootユーザーのパスワードを設定する

rootのパスワードは最初は設定されていないので設定します。

$ mysql -u root

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

データベースユーザーの作成

作業用のユーザーも作成しておきましょう。

mysql> CREATE USER 'ユーザー名'@'localhost' IDENTIFIED BY 'パスワード';

権限も付与しておきます。

mysql> GRANT ALL PRIVILEGES ON * . * TO 'ユーザー名'@'localhost';
mysql> FLUSH PRIVILEGES;

全部の権限与えたけど、必要に応じてユーザー権限を調整しましょう。

データベースの作成

Railsアプリケーションから使用するデータベースも作成しておきます。

mysql> create database rails_todo;

ローカルのRailsアプリケーションをConoHa VPSにアップロードする

ローカルにあるRailsアプリケーションをConoHa VPSにアップロードします。置く場所は作成したユーザー配下にすることにします。

Railsアプリをアップロードする

FTPソフトを使ってアップロードします。以下はCyberduckの画面。

アップロードするのはさっき作成したユーザーの直下にしておきます。

vendor等はアップロードしなくてOKなはず。

bundle installする

bundle installをします。unicornを後で使うので、gemfileになかったら記述しておきましょう。

# mysql2のインストールでエラーが出たので入れておく。
$ sudo dnf install mariadb-connector-c-devel

$ bundle install --without test development

データベースの接続情報を変更する

$ vim /home/kobayashi/rails-todo/config/database.yml

productionの部分に作成したデータベース情報を当てます。(envとかでやった方がいいでしょう)

production:
  <<: *default
  database: 作成したデータベース名
  username: 作成したデータベースのユーザー名
  password: 作成したユーザーのパスワード

Migrateする

データベース情報が正しければmigrateもうまくいくはず。

$ rails db:migrate RAILS_ENV=production

== 20221201052947 CreateTodos: migrating ======================================
-- create_table(:todos)
   -> 0.0432s
== 20221201052947 CreateTodos: migrated (0.0435s) =============================

Unicornの設定をする

アプリケーションサーバーにはunicornを使いたいです。設定ファイルを記述します。

$ vim /home/kobayashi/rails-todo/config/unicorn.rb

listenとpidは自分のアプリケーションのパスにしましょう。

worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true

listen '/home/kobayashi/rails-todo/tmp/unicorn.sock'
pid    '/home/kobayashi/rails-todo/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'])

rakeファイルも作っておきます。

$ vim /home/kobayashi/rails-todo/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/kobayashi/rails-todo/tmp/unicorn.pid").to_i
    rescue Errno::ENOENT
      raise "Unicorn does not seem to be running"
    end
  end

end

Uncornを起動する

ファイルを作成したら起動させます。

$ rake unicorn:start

起動するとこんな感じになりますね。

$ ps -ef | grep unicorn | grep -v grep
kobayas+   92183       1  9 18:00 ?        00:00:01 unicorn master -c /home/kobayashi/rails-todo/config/unicorn.rb -E production -D
kobayas+   92185   92183  0 18:00 ?        00:00:00 unicorn worker[0] -c /home/kobayashi/rails-todo/config/unicorn.rb -E production -D
kobayas+   92186   92183  0 18:00 ?        00:00:00 unicorn worker[1] -c /home/kobayashi/rails-todo/config/unicorn.rb -E production -D
kobayas+   92187   92183  0 18:00 ?        00:00:00 unicorn worker[2] -c /home/kobayashi/rails-todo/config/unicorn.rb -E production -D

Nginxの設定ファイルを記述する

Nginxは設定ファイルを新たに作ってunicornと繋げるようにします。server_nameはConoHa VPSのIPアドレス、rootは自分のアプリケーションにしておきます。

$ sudo vim /etc/nginx/conf.d/rails_todo.conf
server {
    listen       80;
    server_name  IPアドレス;

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

    root /home/kobayashi/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の起動ユーザーが合わないと失敗するので確認しておきます。(Permission Deniedとか出る)

$ ps -eaf | grep nginx

root       92636       1  0 18:30 ?        00:00:00 nginx: master process /usr/sbin/nginx
nginx      92637   92636  0 18:30 ?        00:00:00 nginx: worker process
root       92661   92640  0 18:31 pts/0    00:00:00 grep --color=auto nginx


$ ps aux | grep unicorn
kobayas+   92445  0.1 18.7 227660 88372 ?        Sl   18:19   0:01 unicorn master -c /home/kobayashi/rails-todo/config/unicorn.rb -E production -D
kobayas+   92447  0.0 17.6 227756 83460 ?        Sl   18:19   0:00 unicorn worker[0] -c /home/kobayashi/rails-todo/config/unicorn.rb -E production -D
kobayas+   92448  0.0 16.9 227660 80104 ?        Sl   18:19   0:00 unicorn worker[1] -c /home/kobayashi/rails-todo/config/unicorn.rb -E production -D
kobayas+   92449  0.0 16.9 227660 80120 ?        Sl   18:19   0:00 unicorn worker[2] -c /home/kobayashi/rails-todo/config/unicorn.rb -E production -D
kobayas+   92723  0.0  0.4   6408  2336 pts/0    S+   18:39   0:00 grep --color=auto unicorn

unicornはkobayashiのようなので、nginxの実行ユーザーをkobayashiにしておきます。

$ sudo vim /etc/nginx/nginx.conf
#user www-data;
user kobayashi;

ただこれ本当はどうするのがいいんだろうね。nginx再起動しておきます。

$ sudo service nginx restart

Precompileする

precompileしないと画面が表示されなかったのでします。config/environments/production.rbのcompileをtrueに変更。(これやる必要あるのかよくわからん)

  #config.assets.compile = false
  config.assets.compile = true

precompileします。

$ rails tmp:cache:clear
$ rake assets:precompile RAILS_ENV=production

ただprecompileするとエラー起きましたね。

rake aborted!
Sprockets::ArgumentError: link_tree argument must be a directory
/home/ubuntu/rails-todo/app/assets/config/manifest.js:4

manifest.jsを覗いてみると存在しないフォルダを指定していたので、それを消すととりあえず動きました。ただここもちょっとよくわからないですね。うーん。

ブラウザから確認する

ブラウザにIPアドレス入力して確認してみるとちゃんと動きました。

まとめ

前にさくらのVPSでUbuntuを使って同じようなことをしたから、それと同じよう流れでやったんだけどやっぱりデプロイしんどいですね。途中ほぼ確実にエラー起きるし、なんとか公開できるっていう場合が多いと思います。

ログを見て地道に解消していきましょう。

ログファイルの場所

  • Nginxのログ・・・/var/log/nginx/errro.log
  • Unicornのログ・・・アプリケーション配下/log/unicorn.log
  • production.log・・・アプリケーション配下/log/production.log

あまりすんなりはいかないと思うので、時間がかかるものだと半分諦めながらやってみるといいかもしれません。

  • この記事を書いた人

管理人

各VPSの使い方を紹介します。

-ConoHa VPS