ConoHa VPSでRailsアプリデプロイしたいんだけど?
今回はConoHa VPSでローカルで作成したRailsアプリを公開していきます。(とは言っても試行錯誤しつつ)
この記事でやること
- ConoHa VPSでサーバーの作成
- 作成したサーバーにローカルのRailsアプリをデプロイ
ConoHa VPSでRailsアプリケーションを公開してみたい人はどんなふうにできるのか、なんとなくイメージが湧くかもしれません。
テンプレートは使わない
以前Railsのテンプレートを使うっていうことをやったけど、今回テンプレートは使いません。
-
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で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
あまりすんなりはいかないと思うので、時間がかかるものだと半分諦めながらやってみるといいかもしれません。