Edited at

(初心者向け)vpsを契約して、capistrano3でRailsアプリをデプロイするまで [その1 サーバー設定編]


はじめに


対象・概要

Railsチュートリアルを参考にwebアプリを作ってHerokuにデプロイしてみたけど、軽快に動かない!ドキュメントも英語だし、有料契約は怖い!AWSも機能多すぎて難しそう!って人を対象に国産VPS、ConohaへのRailsアプリのデプロイ方法を記載しています。

私自身、Railsアプリを作ったもののデプロイできず困り果ててましたが、先人の方々の知恵を参考に、なんとかデプロイまでたどり着きました。

自分への備忘録も含め記します。

Capistranoは最初の構築は大変ですが、一度行ってしまえば、あとはコマンドを打つだけでデプロイ、バージョン管理まで行えるので非常に便利です。

なお、冗長な処理・タイポ・情報が古くなってる箇所あるかもしれません。コメントで指摘 or 編集リクエストを送って頂けると助かります。


開発環境


ローカル


  • Mac OS

  • Rails 5.1

  • Ruby 2.4.1
    ### サーバー

  • CentOS 7.4

  • MySQL


参考・謝辞

記事中でも言及していますが、こちらの記事は以下記事をそのままConohaのvpsに適応した形です。

@naoki_mochizukiさん、いつもとてもわかりやすい記事をありがとうございます。

(Capistrano編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで - Qiita


1. Conohaの契約

conohaはGMOが運営しているVPSサービスです。月最低650円と比較的低価格で仮想サーバーを構築できます。国産なので請求書もドキュメントも日本語です。AWSみたいに請求書が英語、$表示で来ることもありません!

サーバーの初期イメージでRaisやkusanagiの環境を構築することも可能です。ただ今回は勉強という意味合いもあり、初期イメージは使用せず、標準のものから構築します。

VPSとは仮想専用サーバー(Virtual private server)のことで、通常のレンタルサーバーでは出来ないような操作も、あたかも自分専用のサーバーが一台あるかのように作業することができるサーバーのことです。

契約についてはConohaのドキュメントを参考にしてください。

第2回:ConoHaでVPSをはじめてみよう!|VPSならConoHa

こちらの記事では、以下構成のサーバーを対象にしています。

スクリーンショット 2017-12-31 15.36.39.png

スクリーンショット 2017-12-31 15.35.04.png

ひとつポイントは、SSH Keyを新規キー登録でpemのキーを生成しているという点です。次のSSH設定で使うので以下手順でダウンロードお願いします。

SSH-Key→新規キー登録→自動生成→ダウンロード


2. SSHの設定

VPSにローカルからSSHログインするまでの設定を行います。

ほぼ以下参考記事そのままです。

ConohaにVPSを設置して、SSHログイン、ポート番号変更、rootログイン禁止までを30分で! - Qiita


2-1 登録したpemキーでログイン

サーバー構築時に登録してダウンロードどした2018xxxxxxx.pemというkeyでサーバーにログインします。ターミナルを開いて以下を入力してください。

なおIPアドレスはサーバーのネットワーク情報に記載されています。

スクリーンショット 2018-01-05 5.14.08.png

ここでは必ずsudoをつけて管理者権限で実行してください。また、途中yes / noと選択肢が出るのでyesと入力してください。

$ # sudo ssh -i [pemキーのパス] root@[serverのipアドレス]

$ sudo ssh -i ~/Downloads/20180105050643.pem root@133.130.116.122

root@133.130.116.122 [05:12:32]
Password:
The authenticity of host '133.130.116.122 (133.130.116.122)' can't be established.
ECDSA key fingerprint is SHA256:BqqPhuXGnZsqryTM07gYrm0dr2E9ruMZ3PaGPJrfpAE.
Are you sure you want to continue connecting (yes/no)? yes


2-2 ユーザーの作成・権限の追加

移行 サーバーでの操作です。

まずrootユーザーだと何かと不便なので、新規にユーザーを作成します。

# ユーザーの追加

$ adduser hoge

# パスワードの設定
$ passwd hoge
# 8文字以上とか制限がありますが、passwd: all authentication tokens updated successfully.と出ればOKです

# 作成したnewuserでログインできるか確認
$ su hoge
# promptの一番左がrootから追加したユーザー名に変わっていればOKです

さらにsudoコマンドが使えるように管理者権限を付与します。

以下参考にしました

CentOS上で管理者ユーザを作成する方法 - Qiita

# rootにユーザー切り替え

$ su root

# 管理者の管理フアイル(/etc/sudoers)に作成したユーザー追加
$ visudo

visudoで開いたファイルを編集します。viでの操作となります。

viなれるまで難しいですが、なれるとものすごい軽快にエディタを操作できます。

操作については以下を参考にしてください。

よく使う Vim のコマンドまとめ - Qiita

Vim初心者に捧ぐ実践的入門 - Qiita

該当箇所は以下のとおりです

root ALL=(ALL) ALLの下に新しく先程作成したユーザーを追加してくだい。それで:wqで保存終了。

.

.
##
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
hoge ALL=(ALL) ALL #追加
.
.

もう一度ユーザーを切り替えてsudoコマンド試してみましょう。

最初、なんか色々出てパスワードを聞かれますが、パスワードを入力し、

無事aaaが出力できれば大丈夫です。

$ su hoge

$ sudo echo aaa

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for hoge: # パスワードを入力
aaa


2-3 SSHログインの許可

sshの設定ファイルでsshログインを許可します。

さらに追加でセキュリティを上げるため、rootログインの禁止、パスワードログインの禁止の設定も行います。

$ sudo vi /etc/ssh/sshd_config

以下箇所を修正します。

# 公開鍵認証を許可

# #でコメントアウトされている場合は#を削除しコメントアウトを解除。
# noの場合はyesに
PubkeyAuthentication yes

# 公開鍵の場所を設定。たぶん初期値で大丈夫です。
AuthorizedKeysFile .ssh/authorized_keys

# rootユーザーでのログインを禁止。
PermitRootLogin no

# パスワードログインを禁止。yesからnoへ変更
PasswordAuthentication no

全部完了したらsshdを再起動します。

$ sudo service sshd restart


2-4 ポート番号の変更

sshのポートが22のままだとSSHへのブルートフォースアタック(ID, PASS 総当たり攻撃)という攻撃をされることがあるので、ポート番号を変更しましょう。

すこし手順が多いのですが、そのまま打ち込めば大丈夫です。

まず、iptablesをインストール。途中に出る選択肢はyでOK

$ sudo yum install iptables-services

次に設定ファイルを編集

$ sudo vi /etc/sysconfig/iptables

開いたら以下箇所を修正

# 下を削除

# -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

# 下を追加
-A INPUT -m state --state NEW -m tcp -p tcp --dport 10022 -j ACCEPT

iptablesの再起動

$ sudo service iptables restart

sshの設定を修正

$ sudo vi /etc/ssh/sshd_config

開いたら任意の箇所に以下を追加

Port 10022

sshdの再起動

$ sudo service sshd restart

これで対策OKです。


2-5 公開鍵の作成

続いて、リモートサーバー上でSSHで使用する鍵を作成。

そして公開鍵をauthorize_keysに追加します

鍵の作成

# 作成したユーザーに切り替え

$ su hoge
$ cd ~

# sshのフォルダ作成
$ mkdir .ssh
$ cd .ssh

# キーペアの作成
$ ssh-keygen -t rsa -b 4096
Enter file in which to save the key: #エンターでOK
Enter passphrase: # 5文字以上のパスフレーズを入力
Enter same passphrase again: #5文字以上のパスフレーズを入力

# 2つの鍵が作成されます
$ ls .
id_rsa id_rsa.pub

# id_rsa.pubが公開鍵です。これを2-3で設定したauthorized_keysにします。(ファイル名を変更)
$ mv id_rsa.pub authorized_keys

# 権限の設定
$ chmod 700 ~/.ssh
$ chmod 600 authorize_keys

# 秘密鍵の内容を確認
# 表示された文字列をクリップボードにコピーしてください
# -----BEGIN RSA PRIVATE KEY-----から
# -----END RSA PRIVATE KEY-----までです。
$ cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
xxxxxxxxxxxx
xxxxxxxxxxxx
xxxxxxxxxxxx
-----END RSA PRIVATE KEY-----


2-6 秘密鍵をローカルのsshに登録

秘密鍵をローカルのsshに登録します。

ここまで完了すれば、あとはssh xxx で簡単にsshでリモートサーバーにアクセスが出来るようになります。

今からの操作はローカルで行うので注意!

サーバー側にいる場合は、exitもしくは別ウィンドウでローカルを開きましょう。

$ cd ~/.ssh

# 鍵の保存場所の作成
$ mkdir conoha_hoge #名前は任意

# 鍵ファイルの作成
$ sudo cd conoha_hoge
$ vi id_rsa
# 先程クリップボードにコピーした内容をそのまま貼り付けて保存

# sshの設定ファイルの作成
$ cd ..
$ vi ssh_config

以下内容を追記します。

HostNameはconohaのIPアドレスです。

Host conoha_hoge

HostName 133.130.116.122
User hoge
Port 10022
IdentityFile ~/.ssh/conoha_hoge/id_rsa

これで設定完了です!!

あとは以下でリモートサーバーにアクセスできるはず!!

$ ssh conoha_hoge

# パスフレーズが聞かれるので作成時のものを入力


2-7 SSH agentへの登録

上記のままで接続はできるのですが、毎回パスフレーズを聞かれるのが面倒です。

なのでssh-agentという便利なものがあるのでそれを使いましょう。

使い方は簡単。以下コマンドで鍵を登録するだけです。

登録すればあとはssh サーバー名でパスフレーズなしのアクセスができます。

SSH agentについては以下が大変参考になりました。

ssh-agentを利用して、安全にSSH認証を行う - Qiita

$ sudo ssh-add -K ~/.ssh/conoha_hoge/id_rsa


3 Rubyの設定

続いてRailsアプリを動かすために無くてはならない、Rubyの設定をします。

git、rbenv、ruby-buildとステップは多いのですが頑張りましょう。

以下すべてサーバー側での処理です。


3-1 Gitのインストール

何はともあれまずgitをインストールしましょう。

rbenvのインストール、capistoranoの設定で使用します。

$ sudo yum -y install git

$ git --version
# version名出力されればOK


3-2 rbenvのインストール・設定

rbenvはrubyのバージョン管理ツールでディレクトリごとに使用バージョンを設定するなど柔軟な開発ができます。

$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv


3-3 ruby-buildのインストール

ruby-burildはrbenv installを実行するためのrbenvのプラグインです。基本的にrbenvとセットでインストールします。

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


3-4 依存パッケージのインストール

rubyをインストールするための関連するパッケージです。これがないと、rbenv installの際にコケます。

$  sudo yum -y install bzip2 gcc openssl-devel readline-devel zlib-devel


3-5 rbenvの読み込み設定

rbenvコマンドを使える用にするために、shel起動時読み込むbash_profileにコードを追加します。

echo xx >> ~/.bash_profile にて追記モードで.bash_profileに書き込んでいます。

# PATHにrbenvコマンドを追加

$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
# rbenvの初期化
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
# bashの再読込
$ source ~/.bash_profile
# rbenvのバージョン確認 バージョンが出ればOK
$ rbenv -v


3-6 rubyのインストール

長くなりましたが、やっとrubyのインストールです。

バージョンについては、ご自身のローカル開発環境と合わせてください。

ネット環境によってはruby installで結構時間かかります。

# ruby 2.4.1のインストール

$ rbenv install 2.4.1
# globalで使用するrubyの設定
$ rbenv global 2.4.1
# rbenvの再起動?
$ rbenv rehash
# rubyのバージョン確認
$ ruby -v


3-7 bundleのインストール

gemを効率よく管理するためのbundleをインストールします。

$ gem install bundle


4 node.jsのインストール

railsでnode.jsが必要なのでこちらもインストールしておきます。

$ sudo yum install nodejs npm --enablerepo=epel  

さらにnpmでyarnもインストールします。

$ sudo npm install -g yarn


5. MySQLの設定

次にリモートサーバーにMySQLをインストールします。

下記記事参考にさせて頂きました。

CentOS 7 に MySQL 5.7 を yum インストールして初期設定までやってみた - enomotodev’s blog


5-1 インストール

CentOSの7系では標準でMariaDBがインストールされているので、まずそれの削除から行います。

以下全てリモートサーバー


# mariadbの削除
$ sudo yum remove mariadb-libs
$ sudo rm -rf /var/lib/mysql

続いてyumにMySQLのリポジトリを登録します

$ sudo rpm -ivh http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm

完了したらパッケージのインストール!

# インストール

$ sudo yum install mysql-community-server mysql-devel
# 確認。バージョン出ればOK
$ mysqld --version

起動と自動起動の設定

# 起動

$ sudo systemctl start mysqld.service
# 自動起動設定
$ sudo systemctl enable mysqld.service


5-2 パスワード、セキュリティ設定

ログインするために、まず自動生成された初期パスワードを確認します。

$ sudo cat /var/log/mysqld.log | grep password

2017-12-31T11:31:07.946947Z 1 [Note] A temporary password is generated for root@localhost: .7ogGO4yokDh
# これの「.7ogGO4yokDh」の部分が初期パスワードです。

確認できたらmysql_secure_installationで初期設定を行います。

以下対話形式で進むので適宜コマンド入力してください。

$ mysql_secure_installation

Securing the MySQL server deployment.

Enter password for user root: # ログファイルから取得した初期パスワードを入力します

The existing password for the user account root has expired. Please set a new password.

New password: # root ユーザの新規パスワードを入力します

Re-enter new password: # 確認用にもう一度入力します
The 'validate_password' plugin is installed on the server.
The subsequent steps will run with the existing configuration
of the plugin.
Using existing password for root.

Estimated strength of the password: 100
Change the password for root ? ((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 # ローカルホスト以外からアクセス可能な root アカウントを削除
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 # test データベースの削除
- 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!

ここで設定するパスワードには大文字小文字英数字+特殊文字で8文字以上という制約があります。それを満たすパスワードを設定しなくてはならないので注意してください。

そんな複雑なパスワード覚えられない!って人は、ひとまず適当に設定したあと、以下記事で解説されている方法でrootなど分かりやすいものに変更してください。

mysql5.7でパスワードを変更する - Qiita


5-3 日本語化

次に日本語を扱うために文字コードをUTF-8に変更します。

以下を参考にさせて頂きました。

mysqlで文字コードをutf8にセットする - Qiita

ちなみに私はこれをし忘れてCapistranoがseedでinsertがコケること1時間。。。

以下mysqlにログインしコンソール内でのコマンド

# まず文字コードを確認

mysql> show variables like "chara%";

# latin1のとこをUTF-8に変更します
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

設定ファイルを修正します

exitでmysqlを停止してコンソール上にて

$  sudo vi /etc/my.cnf

ファイル内の末尾に以下を追記

character-set-server=utf8

[client]
default-character-set=utf8

再起動

$ sudo systemctl restart mysqld.service

再度MySQLにログインして確認

mysql > show variables like "chara%";

# 以下が表示されればOK
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)


5-4 time-zoneを設定

必須ではないですが、アプリでTime-zoneを使うこともあるので最初に設定しておきましょう。

以下参考記事

MySQLでタイムゾーンを設定する - Qiita

Time-zoneのインポートと初期化

$ /usr/bin/mysql_tzinfo_to_sql /usr/share/zoneinfo > ~/timezone.sql

# passwordを聞かれるのでmysqlのパスワードを入力
$ mysql -u root -p -Dmysql < ~/timezone.sql

設定の追加

$ sudo vi /etc/my.cnf

末尾に以下を追加

default-time-zone = 'Asia/Tokyo'

再起動

$ sudo systemctl restart mysqld.service

確認。以下MySQLコンソール

mysql > show variables like '%time_zone%';

# 以下表示が出ればOK
+------------------+------------+
| Variable_name | Value |
+------------------+------------+
| system_time_zone | JST |
| time_zone | Asia/Tokyo |
+------------------+------------+
2 rows in set (0.00 sec)


5-5 MySQLの自動起動設定

サーバーの再起動の際にも、mysqlが自動的に起動するよう設定します。

chkconfig mysqld on

これでMySQLの設定が完了です。


6. Nginxの設定

続いてwebサーバーのNginxの設定を行います。webサーバーとはhttpリクエストに対してレスポンスを返すソフトウェアです。従来は多機能なApacheを採用することが多かったですが、現在はより高速でシンプルに動作するNginxが主流のようです。

以下参考にさせて頂きました。

(Capistrano編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで - Qiita

また、webサーバーの概要、アプリケーション・サーバー(今回の場合はUnicorn)との違いは以下が非常に分かりやすかったです。

Rails開発におけるwebサーバーとアプリケーションサーバーの違い(翻訳) - Qiita


6-1 インストール

yumで一発です。以下サーバーにて

$ cd ~

$ sudo yum install nginx
# 確認。バージョン出ればOK
$ nginx -v


6-2 設定ファイルの編集

リクエストの処理方法、webアプリのディレクトリ設定等を行います。

まず、ファイル作成

$ cd /etc/nginx/conf.d/

$ sudo vi hoge_app.conf # 名前は任意。webアプリの名前とか

続いてファイルの中身を以下のように修正してください。

hoge_appの部分は任意の名称に変えてください。

serer_nameの部分をconohaのipアドレスに変更することも忘れずに

#各種ログのディレクトリ設定

error_log /var/www/hoge_app/current/log/nginx.error.log;
access_log /var/www/hoge_app/current/log/nginx.access.log;
#処理を受け取る最大許容量
client_max_body_size 2G;
upstream app_server {
# 連携するunicornのソケットのパス
server unix:/var/www/hoge_app/current/tmp/sockets/.unicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name xxx.xxx.xxx.xxx; # conohaのipアドレス
#次のリクエストが来るまでの待ち時間(秒
keepalive_timeout 5;
#静的ファイルを読みに行くディレクトリ
root /var/www/hoge_app/current/public;
#キャッシュのディレクトリ
try_files $uri/index.html $uri.html $uri @app;
location @app {
# HTTP headers
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
#エラーページを設置する場所
error_page 500 502 503 504 /500.html;
location = /500.html {
root /var/www/hoge_app/current/public;
}
}

まだ /var/www/hoge_app/フォルダは無いですが、その2で作成するので気に留めずで大丈夫です。


6-3 80番ポートの開放

Nginxが使用する80番ポートを開放します。

sshのポート変更にて使用したiptablesを使います。

これをしないとhttpでの通信が出来ないので注意!

まず設定ファイルを開く

$ sudo vi /etc/sysconfig/iptables

前sshのポート番号変更で設定した10022の下に以下を追記して保存

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

再起動。

$ sudo service iptables restart

開放されてるか確認しましょう。

$ sudo iptables -nL

# 如何表示に含まれていればOK
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80


6-4 Nginxの自動起動設定

サーバーの再起動の際にもNginxが自動的に起動するよう設定します。

chkconfig nginx on

これでNginxの設定が完了です。


7. Githubの公開鍵登録

capisatranoでは、直接ローカルからファイルを送るのではなく、githubなどのホスティングサービスを経由します。なので、サーバー側からgithubへsshで接続できるようにキーペアの作成・登録を行います。

キーペアの作成(サーバー)

$ cd ~/.ssh/

$ mkdir github
$ cd github
# キーペアの作成
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hoge/.ssh/id_rsa): /home/hoge/.ssh/github/id_rsa # 先程作成したフォルダを指定
Enter passphrase (empty for no passphrase): # Enter
Enter same passphrase again: #Eneter

$ cat id_rsa.pub
# 出力をコピーして、githubのコンソールより公開鍵を登録

# 設定ファイルを作成
$ sudo vi ~/.ssh/config
# 以下を記述
Host github
Hostname github.com
User git
IdentityFile ~/.ssh/github/id_rsa

catで表示した公開鍵(id_rsa.pub)の情報は、以下記事を参考にgithubアカウントの公開鍵に追加してください。

gitHubでssh接続する手順~公開鍵・秘密鍵の生成から~ - Qiita

サーバーからgithubへssh接続出来れば完了です。

$ ssh -T github

#確認はyes
#以下のような文章が出力されればOK
Hi kawamataryo! You've successfully authenticated, but GitHub does not provide shell access.

かなり長文となりましたので、続きは(初心者向け)vpsを契約して、Capistrano3でRailsアプリをデプロイするまで その2 ローカル設定編 - Qiitaで記します。