はじめに
CentOS Stream 9が出たのでRails 7環境を構築して既存アプリのRails、Rubyのバージョンアップと移行をやったので、手順を記録した。CentOS8での記事のCentOS9版です。
Vultrの一番安い10GB SSDプランだとCentOS9ではディスクが足りなくなるので25G以上をお勧めします。
激安VPSのVultrで紹介者からのリンク経由でアカウント登録すると$100のクレジットをもらえるので、CentOS7, 8, MySQL 5.7, 8などの組み合わせをいろいろ試しました。このキャンペーンはいつ終わるか分からないので、興味のある方は以下のリンクからアカウント登録してください。あなたはクレジットをもらえるし、私にも多少のクレジットが入るらしいので、Win-Winです。
このリンクで$100もらえます
私もリファラー経由でアカウントを作ったので$100もらえました。これで最初にあれやこれや試すのは無料でできます。
使った環境
サーバOS: CentOS Stream 9
ローカルOS: macOS Monterey Version 12.5.1 (Apple M1)
Ruby 3.1.2 on rbenv
Rails 7.0.3.1
puma 4.3.12
bundler 2.3.21
Capistrano 3.17.1
MySQL 8.0.28
puma 5から --daemon オプションが廃止されてデプロイ時のPuma再起動が面倒臭いのであえてPuma 4を使っている。解決策もあるので時間がある時にPuma5移行をやろうと思う。(今すぐやりたい人は参考記事を参照して下さい。)
1. Vultr VPSインスタンス作成
まっさらから作り直そうと思ったので、新しくインスタンスを作成した。以前は東京サーバーは少し高かったのだが、NJと同額になっていたので東京を選択した。
Startup Script
とSSH Keys
については過去記事Vultr VPSにCentOS7, Ruby on Rails 6, Puma, Capistrano3でのProduction環境デプロイの1-(5)を参考にしてください。
2. ログインアカウントの作成
赤で囲ったアイコンでコンソールにアクセスできるので、自動設定されたrootユーザーのパスワードでログインする。基本的にインターネットに接続されているので、OSがインストールされた直後からDefaultのセキュリティホールを突こうとするハッキング攻撃が始まっているので、一番最初にセキュリティ設定をしてから他の作業をすること。
(1) コンソールログイン
(2) 後でCapistranoで使うアカウントを追加します。
# adduser deploy
# passwd deploy
# gpasswd -a deploy wheel
# mkdir /home/deploy/.ssh
# chmod 700 /home/deploy/.ssh
# vi /home/deploy/.ssh/authorized_keys
> 公開鍵を貼り付ける(Macで作った/Users/あなた/.ssh/vultr.pubの中身を貼り付けます。)
# chmod 600 /home/deploy/.ssh/authorized_keys
# chown -R deploy:deploy /home/deploy/.ssh/
(3) SSHでログインできるか確認する。
初回だけエラーが出ますが以下のようにyesと入れれば次回からは出ません。web consoleはHTTPSを有効化していないとパスワードが平文で流れてしまうので使いません。
$ ssh -i ~/.ssh/vultr2 deploy@1あなたのVPSのIPアドレス
The authenticity of host 'あなたのVPSのIPアドレス (あなたのVPSのIPアドレス)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxx
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'あなたのVPSのIPアドレス' (ED25519) to the list of known hosts.
Activate the web console with: systemctl enable --now cockpit.socket
[deploy@hogehoge ~]$
2. OSの設定
(1) SSHDの構成
$ sudo vi /etc/ssh/sshd_config
> 以下を変更
PermitRootLogin no # rootのリモートログインを不許可
PasswordAuthentication no # パスワード無しでSSHログイン
ClientAliveInterval 10 # SSHがタイムアウトしないように10秒毎にAlive確認
ClientAliveCountMax 6 # 上記を最大6回(つまり60秒)繰り返す
> 変更を反映
$ sudo systemctl reload sshd
ローカルマシンからパスワード無しでSSHログイン
$ ssh -i ~/.ssh/vultr deploy@あなたのVPSのIPアドレス
rootでのリモートログインはできない事を確認する。
$ ssh -i ~/.ssh/vultr root@あなたのVPSのIPアドレス
root@あなたのVPSのIPアドレス: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
もし、間違ってリモートからSSHできなくなってしまった時はView Console
アイコンをクリックしてコンソールを出してrootでログインし、復旧させる。
(2) sudoの設定
deployユーザーにパスワードなしでsudoコマンドを実行できるように設定しました。お好みで設定しても、しなくても良いと思います。
(1)visudoコマンドでsudo権限を付与します。
$ sudo visudo
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
deploy ALL=(ALL) ALL <=この行を追加
## Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL
%deploy ALL=(ALL) NOPASSWD: ALL <=この行を追加
deployグループのユーザーはパスワード無しでsudoできます。
[deploy@vultr ~]$ sudo whoami
root
パスワードを聞かれずにwhoami
できました。
(3) Firewallの設定
$ sudo yum remove -y firewalld
$ sudo yum install -y iptables-services
$ sudo systemctl start iptables
$ sudo systemctl enable iptables
$ sudo /usr/libexec/iptables/iptables.init save
$ sudo vi /etc/sysconfig/iptables
> Web用に80と433をあける。
# Generated by iptables-save v1.4.21 on Tue Mar 10 01:44:41 2020
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [17:1954]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT <=この行を追加
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT <=この行を追加
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Tue Mar 10 01:44:41 2020
> 上記の変更を反映させます。
$ sudo systemctl reload iptables
(4) Swap領域の設定
今回作成したインスタンスはメモリが1GBと少なく、メモリを多く必要とするRailsではメモリ不足になる可能性が高いので、Swap領域を設定します。ページングが多発するとパフォーマンスが悪くなりますが、その際はVultrのプランをUpgradeすれば良いです。(ただし、一度UpgradeするとDowngradeはできません。) 今回は4GBと多めにSwap領域を確保します。
DefaultでSwapファイルが作成されているので一旦Swapを停止させて削除します。
[deploy@vultr ~]$ su
Password:
[root@vultr deploy]# swapoff /swapfile
[root@vultr deploy]# rm /swapfile
rm: remove regular file '/swapfile'? y
Swapファイルを作成してSwap領域にします。
[root@vultr deploy]# dd if=/dev/zero of=/swapfile bs=1M count=4096
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 12.6042 s, 341 MB/s
[root@vultr deploy]# mkswap /swapfile
mkswap: /swapfile: insecure permissions 0644, fix with: chmod 0600 /swapfile
Setting up swapspace version 1, size = 4 GiB (4294963200 bytes)
no label, UUID=b0a8ad95-0d26-4a3f-933b-911a840d7caf
[root@vultr deploy]# swapon /swapfile
swapon: /swapfile: insecure permissions 0644, 0600 suggested.
[root@vultr deploy]# chmod 0600 /swapfile
[root@vultr deploy]# vi /etc/fstab
> 以下が一番下に無い場合は追加します。
/swapfile swap swap defaults 0 0
> /etc/fstabの変更を保存したら、自動マウントされるか試すためにサーバを再起動する。
[root@vultr deploy]# reboot
再起動後、top
コマンドでSwap領域を確認。
[deploy@vultr ~]$ top
top - 02:08:14 up 0 min, 1 user, load average: 0.07, 0.03, 0.01
Tasks: 117 total, 1 running, 116 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 956.5 total, 674.2 free, 267.8 used, 157.1 buff/cache
MiB Swap: 4096.0 total, 4096.0 free, 0.0 used. 688.7 avail Mem
3. MySQL8.0のインストール
DBはお好きなものを使えば良いと思いますが、MySQL8が5.7の2倍速いらしいので、8.0を使います。
(1) MySQLインストール
DefaultでMariaDBが入っている場合はアンインストールしてからMySQLをインストールします。東京のVultrのCentOS9には入ってませんでした。
[root@vultr deploy]# yum list installed | grep maria
[root@vultr deploy]# yum list installed | grep Maria
[root@vultr deploy]# yum install mysql
Last metadata expiration check: 1:34:06 ago on Mon 05 Sep 2022 01:09:18 AM UTC.
Dependencies resolved.
=======================================================================================================================================================================
Package Architecture Version Repository Size
=======================================================================================================================================================================
Installing:
mysql x86_64 8.0.28-1.el9 appstream 2.6 M
Installing dependencies:
mariadb-connector-c-config noarch 3.2.6-1.el9 appstream 11 k
mysql-common x86_64 8.0.28-1.el9 appstream 75 k
Transaction Summary
=======================================================================================================================================================================
Install 3 Packages
Total download size: 2.7 M
Installed size: 59 M
Is this ok [y/N]: y
Downloading Packages:
(1/3): mariadb-connector-c-config-3.2.6-1.el9.noarch.rpm 466 kB/s | 11 kB 00:00
(2/3): mysql-common-8.0.28-1.el9.x86_64.rpm 1.5 MB/s | 75 kB 00:00
(3/3): mysql-8.0.28-1.el9.x86_64.rpm 13 MB/s | 2.6 MB 00:00
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total 5.0 MB/s | 2.7 MB 00:00
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : mariadb-connector-c-config-3.2.6-1.el9.noarch 1/3
Installing : mysql-common-8.0.28-1.el9.x86_64 2/3
Installing : mysql-8.0.28-1.el9.x86_64 3/3
Running scriptlet: mysql-8.0.28-1.el9.x86_64 3/3
Verifying : mariadb-connector-c-config-3.2.6-1.el9.noarch 1/3
Verifying : mysql-8.0.28-1.el9.x86_64 2/3
Verifying : mysql-common-8.0.28-1.el9.x86_64 3/3
Installed:
mariadb-connector-c-config-3.2.6-1.el9.noarch mysql-8.0.28-1.el9.x86_64 mysql-common-8.0.28-1.el9.x86_64
Complete!
[root@vultr deploy]# yum install mysql-server
Last metadata expiration check: 1:42:23 ago on Mon 05 Sep 2022 01:09:18 AM UTC.
Dependencies resolved.
=======================================================================================================================================================================
Package Architecture Version Repository Size
=======================================================================================================================================================================
Installing:
mysql-server x86_64 8.0.28-1.el9 appstream 16 M
Installing dependencies:
mecab x86_64 0.996-3.el9.3 appstream 356 k
mysql-errmsg x86_64 8.0.28-1.el9 appstream 473 k
mysql-selinux noarch 1.0.5-1.el9 appstream 36 k
protobuf-lite x86_64 3.14.0-13.el9 appstream 232 k
Transaction Summary
=======================================================================================================================================================================
Install 5 Packages
Total download size: 17 M
Installed size: 116 M
Is this ok [y/N]: y
(2)MySQLを構成
[root@vultr deploy]# systemctl start mysqld
[root@vultr deploy]# systemctl enable --now mysqld
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.
[root@vultr deploy]# systemctl status mysqld
● mysqld.service - MySQL 8.0 database server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2022-09-05 02:52:25 UTC; 2min 9s ago
Main PID: 2636 (mysqld)
Status: "Server is operational"
Tasks: 37 (limit: 5877)
Memory: 430.5M
CPU: 5.562s
CGroup: /system.slice/mysqld.service
└─2636 /usr/libexec/mysqld --basedir=/usr
Sep 05 02:52:17 vultr systemd[1]: Starting MySQL 8.0 database server...
Sep 05 02:52:17 vultr mysql-prepare-db-dir[2559]: Initializing MySQL database
Sep 05 02:52:25 vultr systemd[1]: Started MySQL 8.0 database server.
[root@vultr deploy]# mysql_secure_installation
Securing the MySQL server deployment.
Connecting to MySQL using a blank password.
VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?
Press y|Y for Yes, any other key for No: y
There are three levels of password validation policy:
LOW Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary file
Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 0
Please set the password for root here.
New password:
Re-enter new password:
Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
Success.
Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
Success.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
- Dropping test database...
Success.
- Removing privileges on test database...
Success.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.
All done!
# vi /etc/my.cnf
> 以下追記
character-set-server = utf8
default_password_lifetime = 0
(3) Railsアプリで使うMySQLユーザーを作成
Railsで使うDBを作り、DBユーザーを作成してGrantします。
# mysql -u root -p
mysql> CREATE DATABASE あなたのアプリ名_production;
mysql> CREATE USER 'DBユーザ名'@'localhost' IDENTIFIED BY 'パスワード';
mysql> GRANT ALL PRIVILEGES ON あなたのアプリ名_production.* TO 'DBユーザ名'@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> exit;
4. 環境構築
Ruby、Bundler、その他の必要なパッケージをインストールする。
(1) Ruby 3.1.2のインストール
[root@vultr deploy]# yum groupinstall "Development Tools"
[root@vultr deploy]# yum -y install libyaml-devel
[root@vultr deploy]# yum install -y openssl-devel readline-devel zlib-devel
[root@vultr deploy]# cd /usr/local
[root@vultr deploy]# git clone https://github.com/sstephenson/rbenv.git rbenv
[root@vultr deploy]# git clone https://github.com/sstephenson/ruby-build.git rbenv/plugins/ruby-build
[root@vultr deploy]# vi /etc/profile.d/rbenv.sh
> 以下を記述してパスを通しておく。
export RBENV_ROOT="/usr/local/rbenv"
export PATH="${RBENV_ROOT}/bin:${PATH}"
eval "$(rbenv init --no-rehash -)"
[root@vultr deploy]# source /etc/profile.d/rbenv.sh
[root@vultr deploy]# rbenv install 3.1.2 <=これが時間がかかる。
[root@vultr deploy]# rbenv global 3.1.2
[root@vultr deploy]# rbenv rehash
(2) Budnler 2のインストール
[root@vultr local]# gem install bundler
Fetching bundler-2.3.21.gem
Successfully installed bundler-2.3.21
Parsing documentation for bundler-2.3.21
Installing ri documentation for bundler-2.3.21
Done installing documentation for bundler after 0 seconds
1 gem installed
(3) node.js をインストール
[root@vultr local]# yum install -y nodejs
[root@vultr local]# node --version
v16.14.0
(4) yarn をインストール
[root@vultr local]# npm install -g yarn
5. Nginxインストール
(1) yumでインストール
[root@vultr local]# yum update
Last metadata expiration check: 2:12:25 ago on Mon 05 Sep 2022 01:09:18 AM UTC.
Dependencies resolved.
Nothing to do.
Complete!
[root@vultr local]# yum info nginx
Last metadata expiration check: 2:12:43 ago on Mon 05 Sep 2022 01:09:18 AM UTC.
Available Packages
Name : nginx
Epoch : 1
Version : 1.20.1
Release : 13.el9
Architecture : x86_64
Size : 39 k
Source : nginx-1.20.1-13.el9.src.rpm
Repository : appstream
Summary : A high performance web server and reverse proxy server
URL : https://nginx.org
License : BSD
Description : Nginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and
: IMAP protocols, with a strong focus on high concurrency, performance and low
: memory usage.
[root@vultr local]# yum install yum-utils
[root@vultr local]# yum install nginx
(2) Start Nginx on Centos 8
[root@vultr local]# systemctl start nginx
[root@vultr local]# systemctl enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
[root@vultr local]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2022-09-05 03:24:17 UTC; 23s ago
Main PID: 24591 (nginx)
Tasks: 2 (limit: 5877)
Memory: 2.0M
CPU: 28ms
CGroup: /system.slice/nginx.service
├─24591 "nginx: master process /usr/sbin/nginx"
└─24592 "nginx: worker process"
Sep 05 03:24:17 vultr systemd[1]: Starting The nginx HTTP and reverse proxy server...
Sep 05 03:24:17 vultr nginx[24589]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Sep 05 03:24:17 vultr nginx[24589]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Sep 05 03:24:17 vultr systemd[1]: Started The nginx HTTP and reverse proxy server.
一応、基本的なコマンドを書いておきます。OSのバージョンとかで少し違うので。
# systemctl stop nginx
# systemctl restart nginx
# systemctl reload nginx
NginxはDefault構成でも動作確認できるので、ブラウザにVultr VPSのIPアドレスを入れて確認します。
(3) Nginxの構成
構成ファイルの場所
- Nginx configuration directory: /etc/nginx
- Nginx root directory: /usr/share/nginx/html
- Master/Global configuration file: /etc/nginx/nginx.conf
5. Rails環境構築
(1) Rails 7のための事前準備
# curl https://dl.yarnpkg.com/rpm/yarn.repo > /etc/yum.repos.d/yarn.repo
# dnf --enablerepo=crb -y install ruby-devel rpm-build make gcc gcc-c++ libxml2 libxml2-devel mariadb-devel zlib-devel libxslt-devel nodejs git yarn
# gem install nokogiri -- --use-system-libraries
# gem install webpack
$ npm install -D webpack webpack-cli
$ npm audit fix --force
$ npm install css-loader style-loader -D
$ bundle exec rails webpacker:install
(2) Rails 7.0.3.1インストール
# gem install rails -v 7.0.3.1
...
Done installing documentation for zeitwerk, thor, method_source, concurrent-ruby, tzinfo, i18n, activesupport, nokogiri, crass, loofah, rails-html-sanitizer, rails-dom-testing, rack, rack-test, erubi, builder, actionview, actionpack, railties, mini_mime, marcel, activemodel, activerecord, globalid, activejob, activestorage, actiontext, mail, actionmailer, actionmailbox, websocket-extensions, websocket-driver, nio4r, actioncable, rails after 51 seconds
35 gems installed
# rails -v
Rails 7.0.3.1
(3) mysql2インストール
# gem install mysql2 -- --with-mysql-config=/usr/bin/mysql_config
Building native extensions with: '--with-mysql-config=/usr/bin/mysql_config'
This could take a while...
Successfully installed mysql2-0.5.4
Parsing documentation for mysql2-0.5.4
Installing ri documentation for mysql2-0.5.4
Done installing documentation for mysql2 after 0 seconds
1 gem installed
(2) Test rails app
動作検証用に適当なアプリを作る。Capistranoでローカル環境からデプロイするので適当でOK。
(1) directory preparation
$ sudo su
[root@vultrguest var]# mkdir /var/www
[root@vultrguest var]# mkdir /var/www/myapp
[root@vultrguest var]# chown -R deploy.deploy /var/www
(2) Gemfile preparation
$ cd /var/www/myapp
$ source /etc/profile.d/rbenv.sh
$ bundle init
Writing new Gemfile to /var/www/myapp/Gemfile
$ vi Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "rails" <= remove "#" here
(3) rails new
$ bundle install --path vendor/bundle
$ bundle exec rails new . -B -d mysql --skip-test
exist
create README.md
create Rakefile
create .ruby-version
create config.ru
create .gitignore
create .gitattributes
conflict Gemfile
Overwrite /var/www/myapp/Gemfile? (enter "h" for help) [Ynaqdhm] Y
$ bundle install --path vendor/bundle
$ rails s
=> Booting Puma
=> Rails 7.0.3.1 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.6.5 (ruby 3.1.2-p20) ("Birdie's Version")
* Min threads: 5
* Max threads: 5
* Environment: development
* PID: 31178
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop
6. Capistrano3でデプロイ
今度はローカルの開発環境で作ったアプリをCapistrano3でデプロイしてみます。
前提条件
- GitHubにSSH公開鍵でローカルからPushできていること。
(1) Vultr VPSにアプリのデプロイ先ディレクトリを準備
$ sudo su
# mkdir /var/www
# mkdir /var/www/myapp
# mkdir /var/www/myapp/shared
# mkdir /var/www/myapp/shared/config
# adduser www
# chown -R www:www /var/www
# chown -R deploy /var/www/myapp
# gpasswd -a deploy www
# gpasswd -a nginx www
(2) デプロイ対象外指定したファイルをコピー
$ scp -i ~/.ssh/vultr config/master.key deploy@SERVER_IP_ADDR:/var/www/myapp/shared/config/
$ scp -i ~/.ssh/vultr config/database.yml deploy@SERVER_IP_ADDR:/var/www/myapp/shared/config/
ここでコピーしたdatabase.ymlのproduction:を編集しておく。
production:
<<: *default
database: myapp_production
username: MySQLに作ったアプリ用ユーザー名
password: MySQLに作ったユーザーのパスワード
(3) Capistrano関連Config
# Use Capistrano for deployment
group :development do
gem 'capistrano'
gem 'ed25519'
gem 'bcrypt_pbkdf'
gem 'capistrano-rbenv'
gem 'capistrano-bundler'
gem 'capistrano-rails'
gem 'capistrano3-puma'
end
Capfile, config/deploy.rbを生成
$ bundle exec cap install STAGES=production
Capfile, config/deploy.rbを設定
# Load DSL and set up stages
require "capistrano/setup"
# Include default deployment tasks
require "capistrano/deploy"
# Load the SCM plugin appropriate to your project:
#
# require "capistrano/scm/hg"
# install_plugin Capistrano::SCM::Hg
# or
# require "capistrano/scm/svn"
# install_plugin Capistrano::SCM::Svn
# or
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
# Include tasks from other gems included in your Gemfile
#
# For documentation on these, see for example:
#
# https://github.com/capistrano/rvm
# https://github.com/capistrano/rbenv
# https://github.com/capistrano/chruby
# https://github.com/capistrano/bundler
# https://github.com/capistrano/rails
# https://github.com/capistrano/passenger
#
# require "capistrano/rvm"
require "capistrano/rbenv"
# require "capistrano/chruby"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
# require "capistrano/passenger"
require 'capistrano/puma'
install_plugin Capistrano::Puma
install_plugin Capistrano::Puma::Daemon
install_plugin Capistrano::Puma::Nginx
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
# config valid for current version and patch releases of Capistrano
lock "~> 3.12.1"
server 'Your Vultr IP ADDR', port: 22, roles: [:app, :web, :db], primary: true
set :application, 'myapp'
set :repo_url, 'git@github.YOU/myapp.git'
set :user, 'deploy'
set :ssh_options, {
forward_agent: true,
user: fetch(:user),
keys: %w(~/.ssh/vultr)
}
# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
# Default deploy_to directory is /var/www/my_app_name
# set :deploy_to, "/var/www/my_app_name"
set :deploy_to, "/var/www/myapp"
# Default value for :format is :airbrussh.
# set :format, :airbrussh
# You can configure the Airbrussh format using :format_options.
# These are the defaults.
# set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto
# Default value for :pty is false
# set :pty, true
# Default value for :linked_files is []
# append :linked_files, "config/database.yml"
# Default value for linked_dirs is []
# append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
append :linked_dirs, '.bundle'
append :linked_files, "config/master.key"
append :linked_files, "config/database.yml"
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets"
# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }
# Default value for local_user is ENV['USER']
# set :local_user, -> { `git config user.name`.chomp }
# Default value for keep_releases is 5
# set :keep_releases, 5
# Uncomment the following to require manually verifying the host key before first deploy.
# set :ssh_options, verify_host_key: :secure
# rbenv
set :rbenv_type, :system
set :rbenv_ruby, File.read('.ruby-version').strip
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :bundle_jobs, 2 <=安いプランなので2。Defaultは4。
# debug log level
set :log_level, :debug <=設定作業中はデバッグモードにした。
(4) nginx-puma連携の事前デプロイ
VPS事前準備
# mkdir /etc/nginx/sites-available
# mkdir /etc/nginx/sites-enabled
# chgrp www sites-available
# chgrp www sites-enabled
capistrano-pumaプラグインで設定ファイル自動生成
これらコマンドで、サーバ上の /etc/nginx/sites-available
と shared/puma.rb
に設定ファイルが作られる。
$ bundle exec cap production puma:nginx_config
00:00 puma:nginx_config
Uploading /tmp/nginx_myapp_production 100.0%
01 sudo mv /tmp/nginx_myapp_production /etc/nginx/sites-available/myapp_production
✔ 01 deploy@Vultr_IP_ADDR 0.200s
02 sudo ln -fs /etc/nginx/sites-available/myapp_production /etc/nginx/sites-enabled/myapp_production
✔ 02 deploy@Vultr_IP_ADDR 0.223s
$ bundle exec cap production puma:config
00:00 puma:config
Uploading /var/www/myapp/shared/puma.rb 100.0%
デプロイ実行
デプロイを実行して、pumaが起動されるところまで正常終了することを確認する。
$ bundle exec cap production deploy
Tips 1:
GitHubをVultrサーバーから読み込めない場合、ローカル開発環境からGitHubにssh接続する時に使っているSSH鍵を以下のコマンドで追加すると直る。GitHubリポジトリを再作成した場合にエラーになったら試すと良い。
ssh-add ~/.ssh/id_rsa
Tips 2:
OpenSSLのエラーが出た場合、 config/master.key
で作成された config/credentials.yml.enc
がデプロイされているか確認する。 ~/.bash_profile
に export RAILS_MASTER_KEY="abc0123456789xyz..."
があるとRAILS_MASTER_KEYが優先されるので、キーが合わずにこのエラーになる。
Tips 3:
Nginx error: (13: Permission denied) while connecting to upstream
でUnixソケットが使えずにブラウザでアクセスすると502エラーになる場合、通常はNginxの実行ユーザーがDefaultのnginxのままになっていて /var/www/myapp/shared/tmp/sockets/puma.sock
にアクセスできない事が原因である場合が多い。Nginx workerプロセスの実行ユーザーがnginxではなくdeployになっているか確認する。
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user deploy; <=ここを確認
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
全てのPermission設定が正しいのにこのエラーが出る場合はSELinuxの制限に引っ掛かっている可能性がある。その場合は次を試す。
$ sudo setenforce Permissive
これでRailsの画面が出た場合はSELinuxのPolicy変更をする。
$ sudo grep nginx /var/log/audit/audit.log | audit2allow
$ sudo grep nginx /var/log/audit/audit.log | audit2allow -M nginx
$ sudo semodule -i nginx.pp
$ sudo setenforce Enforcing
Tips 4:
Command "webpack" not found.
エラーの対応
before "deploy:assets:precompile", "deploy:yarn_install"
namespace :deploy do
desc 'Run rake yarn:install'
task :yarn_install do
on roles(:web) do
within release_path do
execute("cd #{release_path} && yarn install")
end
end
end
end
Tips 5:
Error: error:0308010C:digital envelope routines::unsupported
エラーでアセットプリコンパイルが失敗する場合の原因はNode.jsがV17になってOpenSSL3を使うようになった為である。これを回避するにはNVM(Node Version Manager)をインストールしてNode.jsのLTSバージョンを使うように設定する。
なお、私のVultr環境ではnode.jsがV16なのにこのエラーが発生したが、以下の手順でnode.js V16 LTSをインストールしたらエラーは解消された。
[deploy@vultr ~]$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
NVMを有効化するために一度ログアウトしてdeplyユーザーでログインしてから以下の続きを実行する。
[deploy@vultr ~]$ nvm install --lts
[deploy@vultr ~]$ nvm use --lts
[deploy@vultr ~]$ node -v
v16.17.0
参考記事
Vultr VPSにCentOS8+Rails 6+MySQL8+nginxをインストールしてCapistrano3でデプロイ
Vultr VPSにCentOS7, Ruby on Rails 6, Puma, Capistrano3でのProduction環境デプロイ
CentOS Stream 9 : Install Ruby on Rails 7 - Server World
Nginx error: (13: Permission denied) while connecting to upstream
Command "webpack" not found.#522
[Solved] error:0308010C:digital envelope routines::unsupported
Puma を systemd のユーザーサービスとして起動する