2+
かなり長文になりますが、Rails + Nginx + Unicorn + postgreSQL を使ったAWS(EC2)の環境構築にかなり苦戦したので、備忘録としてメモしておきました。
今回はHello Worldを表示させるだけなので、DBは導入しますが、アプリケーションとDBのやりとりはないものとしています。DBとのやりとりが発生する場合については、
次回のNginx/Unicorn導入編でまとめます。
Contents
【前提】
<ローカル環境>
・仮想サーバー:vagrant
・アプリケーションサーバー:puma
・Ruby 2.3.1
・Rails 5.2.2
・DBサーバー:postgreSQL1.9.6
<本番環境>
・AWS(EC2)
・Webサーバー:Nginx
・アプリケーションサーバー:Unicorn
・Ruby 2.3.1
・Rails 5.2.2
・DBサーバー:postgreSQL1.9.6
<補足>
・AWSアカウントの作成やVPCの作成、インスタンスの生成、ポート開放などは完了
・MacOSで公開鍵と秘密鍵は作成し、AWS上に公開鍵は登録済。
⇒今回使うAWSのインスタンスは自身で作成したものではなく、第三者が作成したAWSのインスタンスを使用する前提にしています。その場合は予め自身のMacOSで公開鍵を作成し、AWSのインスタンスの保有者に登録してもらう必要があります。
【環境構築のイメージ図】
【手順】
①MacOSのシェルからEC2を操作するために、SSH接続でセキュアな通信でEC2インスタンスにログインする
■MacOSのconfigファイルで、どのIPアドレスとの通信の認証時に、秘密鍵を使って公開鍵認証を行うのかを設定する
1 2 3 4 5 6 7 8 |
[.ssf]$vim config Host ec2-user Hostname IPアドレス → 秘密鍵をどの通信との認証時に使用するのかを設定 Port 22 #SSHのポート番号は「22」 User ec2-user IdentityFile ~/.ssh/id_rsa → 秘密鍵があるファイルを設定 |
■SSH通信でEC2インスタンスにログインする(passphraseを入力するので、公開鍵・秘密鍵を作った時に設定したpassphraseは忘れないこと)
1 2 3 4 5 6 7 8 |
MacBook-Pro-2:.ssh hogehoge$ ssh ec2-user Enter passphrase for key '/Users/hogehoge/.ssh/id_rsa': Last login: Fri Mar 8 09:01:11 2019 from ~~~~~~~~~~~~~ __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| |
②現状中身が空っぽのEC2インスタンスを、VirtualBoxと同じ開発環境に構築していく。
■yumを使ってパッケージをインストールしていく。
yum:LinuxのRedHat系ディストリビューション(CentOSやFedora等)で利用されるパッケージ管理ツール
リポジトリ(パッケージ置き場)からパッケージをダウンロードし、インストール、アンインストール、更新をする事ができる。その際、各パッケージの依存関係を自動的に解決し、関連するパッケージがどれなのか教えてくれたり、必要な場合は、関連パッケージをダウンロードしてそのまま更新してくれたりする。また、システム全体を更新する事も可能という優れもの。
インストールするパッケージは下記3つのサイトから抽出して、それぞれのパッケージについて調べて、あくまで主観だが必要そうだと思ったものをインストールした。
※他に必要なものがあれば、後ほどインストールするようにする。
1 2 3 4 5 6 7 8 9 10 |
[ec2-user@ ~]$ sudo yum install -y \ openssl-devel \ libyaml-dev \ curl-devel \ readline-devel \ libreadline-dev \ postgresql96-server \ postgresql96-devel \ postgresql96 \ gcc |
■rbenvのインストール
rbenv:複数バージョンのRubyを切り替えて使うための環境を提供してくれる便利ツール
1 2 3 4 |
[ec2-user@ ~]$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv Cloning into '/home/ec2-user/.rbenv'... ・ ・ |
■PATHを通すことで、rbenvコマンドを使えるようにする
PATHを通す:特定のプログラムを「プログラム名だけで実行できるようにする」こと。例えば、UNIXで「ls」と打てば、ディレクトリ内のファイル一覧を見ることができるが、
この「ls」はデフォルトでPATHが通っているから「ls」というプログラム名だけで実行することができる。
https://qiita.com/nbkn/items/01a11392921119fa0153
PATHを通すための環境変数の設定について(https://qiita.com/soarflat/items/d5015bec37f8a8254380)
・.bash_profileに環境変数を設定
bash:シェルの一種(https://www.sejuku.net/blog/54333#bash)
.bash_profile:環境変数を設定する場所(https://qiita.com/takutoki/items/021b804b9957fe65e093)
1 |
[ec2-user@ ~]$echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile |
・shimsを有効化する
1 |
。[ec2-user@ ~]$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile |
shims(rbenv rehash)
⇒rubyやgemをインストールして使えるコマンド(irb gem rake rails ruby等)をバージョンごとに振り分けるフォルダ。
こういったコマンドをバージョンごとに参照先を切り替えてくれるディレクトリがshims(rbenv rehash)。
・.bash_profileに設定された環境変数を読み込む。これでrbenvコマンドが使えるようになる。
1 |
[ec2-user@ ~]$ source .bash_profile |
■ruby-buildをインストール(rbenv install コマンドが使えるようになるrbenvのプラグイン)
1 |
[ec2-user@ ~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build |
・rbenv rehashでこれまでの処理を有効化
1 |
[ec2-user@ ~]$ rbenv rehash |
■rubyをインストール
1 |
[ec2-user@ ~]$ rbenv install -v 2.3.3 |
・システム全体で使用するrubyバージョンを指定する
1 |
[ec2-user@ ~]$rbenv global -v 2.3.3 |
・rbenv rehashでこれまでの処理を有効化
1 |
[ec2-user@ ~]$ rbenv rehash |
・最後にruby -vでバージョン確認して表示されたらOK
1 2 |
[ec2-user@ ~]$ ruby -v ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux] |
■次にrailsをインストール
・まずは、bundlerをインストール
1 2 3 4 5 6 7 |
#bundlerをインストール [ec2-user@ ~]$ gem install bundler --no-rdoc --no-ri Fetching: bundler-2.0.1.gem (100%) Successfully installed bundler-2.0.1 1 gem installed [ec2-user@ ~]$ bundler -v Bundler version 2.0.1 |
bundler:gem同士の互換性を保ちながら、パッケージの種類やバージョンを管理してくれる仕組み。
基本的に、gemコマンドでインストールするのはBundlerのみで、その他のgemパッケージはBundler経由でインストールする
Bundler概要
Bundlerとは?
・railsをインストール
1 2 3 |
[ec2-user@ ~]$ gem install rails [ec2-user@ ~]$ rails -v Rails 5.2.2 |
■postgresqlをインストール
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[ec2-user@ ~]$ sudo yum localinstall -y https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-6-x86_64/pgdg-ami201503-96-9.6-2.noarch.rpm ・ ・ 完了しました! [ec2-user@ ~]$ sudo yum install -y postgresql96 postgresql96-server postgresql96-libs postgresql96-contrib postgresql96-devel ・ ・ 依存性関連をインストールしました: libxslt.x86_64 0:1.1.28-5.amzn2.0.2 完了しました! |
・postgresqlが起動しているか確認。(下記の状態は、まだ起動していない。起動していれば、3つ以上のプロセスが表示されるはず。)
1 2 |
[ec2-user@ ~ ]$ps aux | grep postgre ec2-user 30757 0.0 0.0 119484 884 pts/0 S+ 14:59 0:00 grep --color=auto postgre |
ps/grepなどのLinuxコマンドについてはこちらを参照
・起動していなければ、起動させる。
1 2 3 4 |
[ec2-user@ ~ ]$ sudo /etc/init.d/postgresql-9.6 initdb Initializing database: [ OK ] [ec2-user@ ~ ]$ sudo /etc/init.d/postgresql-9.6 start Starting postgresql-9.6 (via systemctl): [ OK ] |
■ Gemfileに「gem ‘therubyracer’」を追記
railsではCoffeScripitをJavaScriptにコンパイルする際に、JavaScript runtime が必要になってくる。
MacやWindow PCでは、標準でインストールされているが、それが認識されない場合に下記のようなエラーが出るので、エラーが出たら次に紹介する2つの方法のいずれかで解決する。
1 |
Could not find a JavaScript runtime. |
このエラーを解消する方法は2つ。
①node.jsをインストールする
②gemをインストールする
今回のアプリケーション開発ではnode.jsは使わない想定なので、②の方法を採用しています。
node.jsを使う想定の方は①の方法をした方が良いと思われる。
1 |
sudo yum install nodejs npm --enablerepo=epel |
③MacOS(VirtualBox)で開発したアプリケーションをGitHubからEC2でgit cloneする。
※このフェーズでは、EC2がクライアントで、GitHubがサーバーというクライアント/ サーバーの関係になっている。
※Gitの仕組みについてはこちら
■gitに関する設定ファイル(.gitconfig)を生成
→.gitconfigはホーム直下(~/)にあり、対象範囲は該当ユーザーの全リポジトリという設定にする
gitconfigについて(https://note.nkmk.me/git-config-setting/)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[ec2-user@ ~ ] vi .gitconfig [user] #gitの該当ユーザー name = 自分のGitHubnのユーザー名 email = 自分のGitHubに登録しているメールアドレス [color] #MacのTerminalで、gitを実行したときの色設定 ui = true # githubの場合 [url "github:"] #pull、pushのための設定 InsteadOf = https://github.com/ InsteadOf = git@github.com: |
■git cloneするアプリケーションを配置するディレクトリを作成する
/var:ログやキャッシュなど、可変的システムデータ(動的ファイル)。一時的なデータとしては/tmpと同じだが、再起動しても消去されずに残る
参照:Linuxの基本的なディレクトリ構成(https://oxynotes.com/?p=5987#32)
1 2 3 4 5 |
[ec2-user@ ~]$ cd / [ec2-user@ /]$ cd var [ec2-user@ var]$ sudo mkdir www [ec2-user@ var]$ cd www [ec2-user@ www]$ sudo mkdir rails |
この段階でvarとwwwとrailsディレクトリの所有者をrootから自分に変えておくと
後でパーミッションを触る必要がないので、かなり楽になる。
パーミッションについては、こちらを参照
1 |
[ec2-user@ ~]$ chown ec2-user var www rails #var www railsの所有者をec2-userに変更する。chown=change ownerの略 |
■EC2のシェルからGitHubを操作するために、SSH接続でセキュアな通信を確保する
SSH接続=公開鍵認証方式を利用する=公開鍵と秘密鍵を作成する必要がある。
公開鍵認証について
・EC2のLinuxで公開鍵と秘密鍵を作る
1 |
[ec2-user@ ~ .ssh]$ ssh-keygen -t rsa |
ちなみにSSH Keyは解読されないようにするならば4096bitで生成するのが、おすすめです。
・2つの鍵が格納されているファイルができているか確認
1 2 |
[ec2-user@ ~ .ssh]$ ls authorized_keys aws_git_rsa aws_git_rsa.pub |
・EC2 Linuxのconfigファイルで、どのIPアドレスとの通信の認証時に、秘密鍵を使って公開鍵認証を行うのかを設定する
1 2 3 4 5 6 7 |
[ec2-user@ ~ .ssh]$ vi config Host github Hostname github.com→ 秘密鍵をどのURLとの認証時に使用するのかを設定 User git IdentityFile ~/.ssh/aws_git_rsa → 秘密鍵があるファイルを設定 |
・今度はサーバー(GitHub)に認証用の公開鍵を登録する。
まずは、ここにログイン(https://github.com/settings/keys)
右上の「New SSH key」ボタンから公開鍵名と公開鍵を登録する。
・SSHはパーミッションのセキュリティが甘いと接続する際にエラーで弾かれることもあるので、
パーミッションを厳しく設定しておく。ちなみに権限は「ls -l」コマンドで見ることができる。
1 2 3 4 5 6 7 |
[ec2-user@ ~ .ssh]$ chmod 600 ~/.ssh/config [ec2-user@ ~ .ssh]$ ls -l 合計 16 -rw------- 1 ec2-user ec2-user 1563 3月 7 18:37 authorized_keys -rw------- 1 ec2-user ec2-user 1766 3月 8 12:09 aws_git_rsa -rw-r--r-- 1 ec2-user ec2-user 438 3月 8 12:09 aws_git_rsa.pub -rw------- 1 ec2-user ec2-user 188 3月 8 12:16 config |
■GitHubからEC2でgit cloneアプリケーションを配置する
1 2 |
[ec2-user@ ~ .ssh]$ cd /var/www/rails/ [ec2-user@ ~ rails]$ git clone https://github.com/~~~~~~~.git |
④Railsサーバーを起動してみる
・ここで一度、bundle install
1 |
bundle install |
もし、ここで下記のようなエラーが起こったら、postgresql-develをインストールすれば解消するはず。https://qiita.com/pugiemonn/items/197301776b68d0445eb7
1 2 3 4 5 6 7 |
・ ・ checking for pg_config... no No pg_config... trying anyway. If building fails, please try again with --with-pg-config=/path/to/pg_config checking for libpq-fe.h... no Can't find the 'libpq-fe.h header |
■postgreSQLにログインし、ユーザー名とデータベースがvagranrt環境と同じかどうか確認する
postgreSQLにはログインの際の認証方法がいくつかあるが、
今回はIdent方式(シェルのユーザーとpostgresqlのユーザーが一致しているかどうかで認証する)を採用しています。
ログインの際に、認証に失敗したら、下記のようなエラーが出る。
1 2 3 4 |
PG::ConnectionBad (FATAL: ユーザ"hogehoge"のIdent認証に失敗しました ): PG::ConnectionBad (FATAL: ユーザ"hogehoge"のIdent認証に失敗しました ): |
・まずは正常に動作しているVagrant環境のpostgreSQLにログイン
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[~/]$ psql -U vagrant psql (9.2.24) "help" でヘルプを表示します. vagrant=# \du ロール一覧 ロール名 | 属性 | メンバー ----------+----------------------------------------------------------------------+---------- postgres | スーパーユーザ, ロールを作成できる, DBを作成できる, レプリケーション | {} test | スーパーユーザ | {} vagrant | スーパーユーザ | {} |
DB所有者とOSユーザー名を見てみると
DBの所有者とシェルを実行しているOSユーザー名がvagrantで一致している。
・EC2でもpostgresqlにログインしてみる。
1 2 |
[ec2-user@ ~ config]$ psql -U ec2-user psql: FATAL: ロール"ec2-user"は存在しません |
もし、このエラーが出た場合はpostgresqlのインストール時にデフォルトで作成される「postgres」にユーザーをスイッチさせて、ログインする。
1 2 3 4 |
[ec2-user@ ~]$ su - postgres postgres=# |
気になるユーザーは・・・本来であれば「ec2-user」にならないといけないのにバラバラ。
1 2 3 4 5 6 7 |
postgres=# \du List of roles Role name | Attributes | Member of -------------------+------------------------------------------------+----------- pg_signal_backend | Cannot login | {} postgres | Superuser, Create role, Create DB, Replication | {} hogehoge | | {} |
vagrantと同じ環境にするために、ロール属性を付加したユーザー(ec2-user)を作成する。
まずは、ユーザー名をec2-userに変える。そして、変更したユーザーにスーパーユーザーの属性を付加して、ユーザー名等は違ってもvagrantと同じ状態にする。
今回はpostgresqlというデータベースをSQLで操作するので、文の最後に「;」を忘れないように注意すること。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
postgres=# alter role hogehoge rename to "ec2-user"; NOTICE: ロール名が変更されたためMD5パスワードがクリアされました ALTER ROLE postgres=# \du List of roles Role name | Attributes | Member of -------------------+------------------------------------------------+----------- ec2-user | | {} pg_signal_backend | Cannot login | {} postgres | Superuser, Create role, Create DB, Replication | {} postgres=# alter role "ec2-user" superuser; ALTER ROLE postgres=# \du List of roles Role name | Attributes | Member of -------------------+------------------------------------------------+----------- ec2-user | Superuser | {} pg_signal_backend | Cannot login | {} postgres | Superuser, Create role, Create DB, Replication | {} |
ここで再度、ec2-userでpostgresqlにログインできるか試すと。
1 2 |
[ec2-user@ ~ sample_app]$ psql psql: FATAL: データベース"ec2-user"は存在しません |
今度はデータベースが存在しないというエラーが出る可能性がある。
念のためにデータベースも見てみると・・・Vagrantと比較して不足が多いことがある。
【Vagrant】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
vagrant=# \l データベース一覧 名前 | 所有者 | エンコーディング | 照合順序 | Ctype(変換演算子) | アクセス権 --------------------------+----------+------------------+-------------+-------------------+----------------------- sample_app_development | vagrant | UTF8 | en_US.UTF-8 | en_US.UTF-8 | sample_app_test | vagrant | UTF8 | en_US.UTF-8 | en_US.UTF-8 | postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres test | test | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | vagrant | vagrant | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | (7 行) |
【ec2-user】
1 2 3 4 5 6 7 8 9 10 |
postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (3 rows)<span style="font-size: 14px;" data-mce-style="font-size: 14px;"> </span> |
そこで、不足分を追加していく。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
postgres=# create database "ec2-user" owner "ec2-user"; CREATE DATABASE postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- ec2-user | ec2-user | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (4 rows) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
ec2-user=# create database "sample_app_development" owner "ec2-user"; CREATE DATABASE ec2-user=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges --------------------------+----------+----------+-------------+-------------+----------------------- ec2-user | ec2-user | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | sample_app_development | ec2-user | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (5 rows) |
<その他参照ページ>
userとパスワードを設定
→設定内容によっては、database.ymlに変更を追記しておくこと。
【user名の変更】
【ロールの変更】
【ロールの属性】
【ロール確認】
これで、rails serverを立ち上げると上手く起動するはず。
※ここでは、「sample_app」というアプリケーションをgit cloneしてきたと仮定。
1 |
[ec2-user@ ~ sample_app]$ rails s |
かなり長文になりましたが、次回は、Nginx/Unicorn導入編です。
2+