LoginSignup
4
5

More than 3 years have passed since last update.

Rails Tutorialの知識から【ポートフォリオ】を作って勉強する話 #18 EC2環境構築, Nginx+Puma+Capistrano編

Last updated at Posted at 2020-02-05

こんな人におすすめ

  • プログラミング初心者でポートフォリオの作り方が分からない
  • Rails Tutorialをやってみたが理解することが難しい

前回:#17 VPC環境構築編
番外:#17.5 MySQL導入編
次回:#18.5 環境変数, Gmail送信設定編

この記事は、動画を観た時間を記録するアプリのポートフォリオです。
今回はRailsポートフォリオのデプロイのためにEC2を構築します。
クライアントにCloud9で使っているEC2、ホストに前回構築したEC2を使います。
なお、VPC構築が完了した前提で進めます(VPC構築は#17)。

今回の流れ

  1. 完成のイメージを理解する
  2. EC2そのものを設定する
  3. 各パッケージをインストールする
  4. GitHubと連携し、ポートフォリオをクローンする
  5. RDSを接続する
  6. Nginxをインストール、設定する
  7. Pumaを設定する
  8. Capistranoを導入する
  9. その他の設定をする
  10. アプリケーションをデプロイする

完成のイメージを理解する

前回のVPCに引き続き、今回はEC2内を構築します。
はじめに、EC2そのものの設定をします。

アプリケーションをデプロイするには、いくつか必要なパッケージがあります。
それらのパッケージを、パッケージ管理できるyumでダウンロードします。

EC2にポートフォリオを配置するには、GitHubを使います。
VPCに構築したRDSを接続する必要もあります。

webサーバーにNginx、アプリケーションサーバーにPumaを使います。
Nginxは、webアプリケーションへのリクエストを処理するために必要です。
Pumaは、webアプリケーションを動かすために必要です。
Rails開発におけるwebサーバーとアプリケーションサーバーの違い(翻訳)

デプロイの自動化するためには、Capistranoを使います。

それでは、EC2内の環境を構築していきます。

EC2そのものを設定する

まずは、EC2そのものの設定を行います。
ここでの手順は以下の通りです。

  • yumをアップデートする
  • ユーザーを登録する
  • SSHの設定をする
  • タイムゾーンと文字コードを変更する

yumをアップデートする

パッケージをインストールする前に、yum自体のアップデートを行います。
yumは、AmazonLinux2起動時にデフォルトでインストールされています。

server
$ sudo yum update

ユーザーを登録する

まずは新たにルート権限を持つ、EC2ユーザーを登録します。
以下は、ユーザーの登録、パスワードの登録、ルート権限の編集を行う手順です。

server
$ sudo adduser hoge
(adduser以降は好きな名前を入力)
$ sudo passwd hoge
$ sudo visudo
## Allow root to run any commands anywhere
root           ALL=(ALL)       ALL
hoge           ALL=(ALL)       ALL

rootの下にユーザーを同じように追加できたらOKです。
後は、作成したユーザーに切り替えます。

server
$ sudo su - hoge

これでユーザーの登録は完了です。

SSHの設定をする

クライアントの公開鍵をサーバーに預けて、作成したEC2ユーザーに接続できるようにします。
まずはクライアント側で秘密鍵・公開鍵を作成します。
以下はクライアント側の作業です。

Cloud9
$ cd ~/.ssh
$ ssh-keygen -t rsa
Enter file in which to save the key ():lantern_key_rsa(自分のアプリ名)
Enter passphrase (empty for no passphrase):何もせずエンター
Enter same passphrase again:何もせずエンター
$ vim config

次に作成した鍵の使用用途を設定します。

~/.ssh/config
Host lantern_key_rsa
  Hostname 設定したElastic IP
  Port 22
  User 作成したユーザー名
  IdentityFile ~/.ssh/latnern_key_rsa(自分のアプリ名)
Cloud9
$ cat lantern_key_rsa.pub
中身をコピーする

最後に、サーバー側で公開鍵を登録します。
以下はサーバー側の作業です。

server
$ mkdir .ssh
$ chmod 700 .ssh
$ cd .ssh
$ vim authorized_keys
~/.ssh/authorized_keys
コピーした公開鍵を貼り付ける
server
$ chmod 600 authorized_keys
$ exit
$ exit

クライアント側でログインできるか確認します。

Cloud9
$ ssh lantern_key_rsa

以上で鍵の設定は完了です。

タイムゾーンと文字コードを変更する

日本での使用を最適化するよう、EC2を設定します。

server
$ sudo vi /etc/sysconfig/clock
/etc/sysconfig/clock
ZONE="Asia/Tokyo"
UTC=true
server
$ sudo vi /etc/sysconfig/i18n
/etc/sysconfig/i18n
LANG="ja_JP.UTF-8"

以上でタイムゾーンと文字コードを変更は完了です。

各パッケージをインストールする

デプロイに必要なパッケージをインストールします。
以下をインストールしていきます。

  • Gitなど
  • MySQL
  • Node.js
  • Ruby
  • Bundler

Gitなど

Gitなどをインストールします。
インストールするものには以下が含まれています。

  • Git
  • C#とC++のコンパイラ
  • コンパイルの必要があるgemライブラリ
server
$ sudo yum install git make gcc-c++ patch openssl-devel libyaml-devel libffi-devel libicu-devel libxml2 libxslt libxml2-devel libxslt-devel zlib-devel readline-devel ImageMagick ImageMagick-devel epel-release

MySQL

サーバー側で使用するデータベース、MySQLをインストールします。

server
$ sudo yum install http://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
$ sudo yum install mysql mysql-devel mysql-server mysql-utilities

参考になりました↓
MySQL 8.0 を yum でインストール&設定メモ
MySQL Yum Repository

Node.js

Railsの一部のコンパイルにはNode.jsが使われています。
Node.jsを使うために、以下をインストールします。

  • EPEL(yumで使える追加リポジトリ)
  • npm(Node.js内のパッケージマネージャー)
  • n(npmで動くNode.js自体のパッケージマネージャー)
server
$ sudo amazon-linux-extras install epel
$ sudo yum install nodejs npm
$ sudo npm install -g n
$ sudo n stable
$ node -v

Node.jsを調べるとよく出てくるnvm、npm、nの各違いについてざっくり紹介します。

  • nvm → Node.js自体のバージョン管理
  • npm → Node.jsで作られたパッケージの管理
  • n → npmで動くNode.js自体のバージョン管理

参考になりました↓
CentOS 7に最新版のNode.jsをインストールしてみよう!
nvm と n の違い

Ruby

RailsはRubyで動くのでインストールします。
Rubyを使うために以下をインストールします。

  • rbenv(Rubyのパッケージマネージャー)
  • ruby-build(rbenvのプラグイン、rbenvとセットで使う)
server
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source .bash_profile
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
$ rbenv rehash
$ rbenv install -v 2.6.3
$ rbenv global 2.6.3
$ rbenv rehash

Gitからrbenvをクローンした後、パスを通したり「色々」しています。
その後ruby-buildをクローンして、rubyをインストールしています。

パスを通すことについては、参考記事などから理解しておきましょう。
「色々」については、深掘りしなくて結構です。

参考になりました↓
rbenv(公式)
rbenv + ruby-build はどうやって動いているのか
Pathを通すとは、環境変数とは

Bundler

サーバー側でもBundlerを使用するので、インストールします。

server
$ rbenv exec gem install bundler
$ rbenv rehash

以上でひとまずのパッケージをインストールしました。
次に進みます。

GitHubと連携し、ポートフォリオをクローンする

サーバー側にポートフォリオを配置します。
GitHubと連携し、ポートフォリオをクローンします。
ここでの作業は以下の通りです。

  • Git、GitHubの設定ファイルをつくる
  • ポートフォリオ用のディレクトリをつくる
  • GitHubとSSH接続する鍵をつくる
  • GitHubに公開鍵をアップする
  • GitHubに接続、クローンする

Git、GitHubの設定ファイルをつくる

Git、GitHubに関する設定を記述します。

server
$ vi .gitconfig
.gitconfig
[user]
  name = Gitに登録したユーザー名
  email = Gitに登録したメールアドレス

[color]
  ui = true

[url "github:"]
    InsteadOf = https://github.com/
    InsteadOf = git@github.com:

ポートフォリオ用のディレクトリをつくる

ポートフォリオを配置するディレクトリを作ります。
webアプリケーションの配置には/var/wwwが用いられます。

server
$ cd /
$ sudo chown hoge var
(hogeはEC2で作成したユーザー名)
$ cd var
$ sudo mkdir www
$ sudo chown hoge www 
$ cd www
$ sudo mkdir rails
$ sudo chown hoge rails

GitHubとSSH接続する鍵をつくる

本来、サーバー側に鍵を置くのは危険です。
後にこの鍵をクライアント側で管理しますが、とりあえずの接続を試みます。

server
$ cd ~
$ cd chmod 700 .ssh
$ cd .ssh
$ ssh-keygen -t rsa
Enter file in which to save the key (/home/hoge/.ssh/id_rsa): aws_git_rsa
$ vi config
~/.ssh/config
Host github
  Hostname github.com
  User git
  IdentityFile ~/.ssh/aws_git_rsa
server
$ cat aws_git_rsa.pub
表示された公開鍵をコピー

GitHubに公開鍵をアップする

作った公開鍵をGitHubにアップします。

GitHubにログイン
→ 右上アイコンから『Settings』 → 『SSH and GPG keys』 → 『New SSH key』

Title:hoge
Key:コピーした公開鍵
『Add SSH key』

参考になりました↓
GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~

GitHubに接続、クローンする

SSHを用いてGitHubに接続し、ポートフォリオをクローンします。

server
$ chmod 600 config
$ ssh -T github
Are you sure you want to continue connecting (yes/no)? yes

ブラウザでGitHubを開く
リポジトリ『自分のアプリ名』 → 『Clone or download』 → 『Use SSH』 → コピー

server
$ cd /var/www/rails
$ git clone コピーしたものをペースト
$ cd /var/www/rails
$ cd ls

ここに自分が作成したアプリのファイルがあれば成功です。

RDSを接続する

EC2からRDSに接続します。

AWSにログイン → AWSマネジメントコンソール『RDS』
画面左のダッシュボード『データベース』 → 『自分のアプリ名』 → 下部タブ『接続とセキュリティ』のエンドポイントをコピー

通常の場合

server
$ mysql -h コピーしたエンドポイント -P 3306 -u root -p
Enter password:MySQLのユーザーのパスワード(設定していない場合は何もせずエンター)
mysql
mysql> show databases;

#17.5の手順でMySQLを導入した場合

server
$ mysql -h コピーしたエンドポイント -P 3306 -u ①任意の名前 -p
Enter password:②任意のパスワード
mysql
mysql> show databases;

ここに自分のアプリ名のDBが表示されたら成功です。

参考になりました↓
0から始めるAWS入門④:RDS編
EC2からRDS(MySQL)に接続できない。セキュリティグループの設定について・・・

Nginxをインストール、設定する

webサーバーであるNginxのインストール、設定をします。

server
$ sudo yum install nginx
$ cd /etc/nginx
$ mkdir conf.d
$ cd conf.d
$ sudo vi lantern.conf(自分のアプリ名)
/etc/nginx/conf.d/lantern.conf
# ログに関するファイルの場所
error_log  /var/log/nginx.error.log;
access_log /var/log/nginx.access.log;
# クライアントから送られるボディの上限
client_max_body_size 2G;

# Pumaとやり取りするための通信路
upstream app_server {
  server unix:///var/www/lantern/shared/tmp/sockets/puma.sock fail_timeout=0; # 自分のアプリ名
}

# サーバーに関する情報(バーチャルホストに使用される)
server {
# ポート
  listen 80;
# 処理するサーバー名
  server_name サーバー側のIP(Elastic IP);
# ドキュメントルートの設定
  root /var/www/lantern/current/public; # 自分のアプリ名

# http://〇〇/でアクセスした時、下記のファイルを左から探すようにする
  try_files $uri/index.html $uri.html $uri @app;

# 内部リダイレクトの処理
  location @app {
# バックエンドサーバーに送信するヘッダーを定義し直す
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
# プロキシのパス(おそらくPumaに渡す)
    proxy_pass http://app_server;
  }

# エラー時のページ表示先
  error_page 500 502 503 504 /500.html;
  location = /500.html {
    root /var/www/lantern/current/public; # 自分のアプリ名
  }
}

Nginxをインストールすると、ある程度の処理がデフォルトで記述されます。
公式ドキュメントなどを見つつ、それを参考に設定を行います。

とりわけ大事な部分はこちらです。

upstream app_server {
  server unix:///var/www/lantern/shared/tmp/sockets/puma.sock;
}

アプリケーションサーバーにPumaを使うので、ソケットを設定します。
これによりPumaとの連携が可能です。

参考になりました↓
documentation | nginx(公式)

Pumaを設定する

アプリケーションサーバーであるPumaを設定します。
しかしPumaは後述のCapistranoで管理するので、ここでの設定は不要です。

Capistranoを導入する

デプロイを自動化する、Capistranoを導入します。
ここでの手順は以下の通りです。

  • Gemを追加し、ファイルを生成する
  • Capfileを編集する
  • config/deploy/production.rbを編集する
  • config/deploy.rbを編集する

Gemを追加し、ファイルを生成する

Gemに'capistrano'を追加します。
それ以外は、Capistranoのタスクを追加させるために必要なGemです。
以下は、クライアント側での作業です。

Gemfile

group :development, :test do
+ gem 'capistrano'
+ gem 'capistrano-bundler'
+ gem 'capistrano-rails'
+ gem 'capistrano-rbenv'
+ gem 'capistrano-rbenv-vars'
+ gem 'capistrano3-puma'
end

cap installで、Capistranoのファイルを生成します。

Cloud9
$ bundle install
$ cap install

Capfileを編集する

これから自分の環境に合わせてCapistranoのファイルを編集します。
まずは、タスクの読み込みを行うCapfileです。
タスクとは、Capistranoで処理を行うまとまりです。

Capfile
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/scm/git'
require 'capistrano/puma'
require 'capistrano/console'

install_plugin Capistrano::SCM::Git
install_plugin Capistrano::Puma

Dir.glob('lib/capistrano/tasks/*.rb').each { |r| import r }

参考になりました↓
Capistrano3のデプロイフレームワークの使い方
Capistrano3におけるRailsのデプロイタスクの内部実装

config/deploy/production.rbを編集する

環境ごとの設定を記述します。

config/deploy/production.rb
server "サーバー側EC2のIP", user: "サーバー側のユーザー名", roles: %w{app db web}

set :ssh_options, {
  keys: %w(~/.ssh/lantern_key_2_rsa),
  forward_agent: true
}

config/deploy.rbを編集する

タスクを記述します。
と言っても、実はほとんどの処理がCapfileによって行われています。

config/deploy.rb
# Capistranoのバージョン指定
lock "~> 3.11.2"

# Capistranoでの必須の設定
set :application, "自分のアプリ名"
set :repo_url, "git@github.com:githubのユーザー名/アプリ名.git"

# Pumaに関する設定(後述)
# ソケットの場所、Nginxとのやり取りに必要
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"
# サーバー状態を表すファイルの場所
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
# プロセスを表すファイルの場所
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
# ログの場所
set :puma_access_log, "#{shared_path}/log/puma.error.log"
set :puma_error_log, "#{shared_path}/log/puma.access.log"

# タスクでsudoなどを行う際に必要
set :pty, true
# シンボリックリンクのファイルを指定、具体的にはsharedに入るファイル
append :linked_files, "config/master.key"
# シンボリックリンクのディレクトリを生成
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system", "public/uploads", "public/storage"
# 環境変数の設定
set :default_env, { path: "/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH" }
# 保存しておく過去分のアプリ数
set :keep_releases, 3

namespace :deploy do
  desc 'Create database'
  task :db_create do
    on roles(:db) do |host|
      with rails_env: fetch(:rails_env) do
        within current_path do
          execute :bundle, :exec, :rails, 'db:create'
        end
      end
    end
  end

  desc 'Restart application'
  task :restart do
    on roles(:app), in: :sequence, wait: 5 do
      invoke 'puma:restart'
    end
  end
end

Capistranoの構文について解説します。

# 変数をセットします
set :キー, "値"
# 値を呼び出します
fetch(:キー)
# タスクを追加します
namespace :hoge do
  task :fuga do
  end
end

Capistranoはshell内でこのように使います。

# デプロイを行う場合
$ cap production deploy
# deployのうち、タスクdb_createを行う場合
$ cap production deploy:db_create
# 例)hogeのタスク、fugaを行う場合
$ cap production hoge:fuga

Pumaの設定について解説します。

capistrano3-pumaによって、CapistranoでPumaを動かすことが可能になります。
本来Pumaの設定は、config/puma.rbに記載されています。
しかし、config/deploy.rbでこの辺りの設定が補われます。

shared_pathについて解説します。

Capistranoでは、1回のデプロイごとにreleasesにまとめられます。
そのうち、最新のものをcurrentとしてデプロイしています。
そして、その中の共有できるファイルはsharedにまとめられています。
そのパスをそれぞれrelease_path、current_path、shared_pathと表現できます。

参考になりました↓
capistranoで設定される変数の値一覧の表示方法
What does deploy:initial do in Capistrano task

備考:Capistranoで使われる変数一覧

[設定が必須の変数]
:application
The name of the application.
:repo_url
URL to the repository.

[設定が任意の変数]
:deploy_to
default: -> { "/var/www/#{fetch(:application)}" }
:scm
default: :git
:branch
default: 'master'
:svn_username
When using :svn, provides the username for authentication.
:svn_password
When using :svn, provides the password for authentication.
:svn_revision
When using :svn, set the specific revision number you want to deploy.
:repo_path
default: -> { "#{fetch(:deploy_to)}/repo" }
:repo_tree
default: None. The whole repository is normally deployed.
:linked_files
default: []
:linked_dirs
default: []
:default_env
default: {}
:keep_releases
default: 5
:tmp_dir
default: '/tmp'
:local_user
default: -> { ENV["USER"] || ENV["LOGNAME"] || ENV["USERNAME"] }
:pty
default: false
:log_level
default: :debug
:format
default: :airbrussh
:shared_directory
default: shared
:releases_directory
default: releases
:current_directory
default: current

その他、変数はこちら↓
Configuration | Capistrano(公式)
パスに関する変数 | Capistrano(公式)
capistrano-puma(GitHub)

その他の設定をする

その他デプロイに必要な設定をします。
ここでの手順は以下の通りです。

  • 本番環境時のシークレットキーを有効にする
  • サーバーに秘密鍵を置かないようにする

本番環境時のシークレットキーを有効にする

秘匿情報の管理のために、シークレットキーを有効にします。
まずは本番環境でのシークレットキーを必須にします。

config/environments/production.rb
# 中略
# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
config.require_master_key = true

次に、サーバー側にmaster.keyを設置します。

Cloud9
$ scp -i ~/.ssh/lantern_key_2_rsa config/master.key ユーザー名@IPアドレス:/var/www/lantern_app/shared/config/

参考になりました↓
Rails5.2から導入されたcredentials.yml.encを極める

サーバーに秘密鍵を置かないようにする

今のところGitHubの秘密鍵をホストサーバーに置いてしまっています。
セキュリティ上よくないので、クライアント側で管理します。
具体的にはssh-agentを用いて、サーバーからでもGitHubが使えるようにします。

GitHub用の鍵をつくる

再びGitHub用の鍵を作ります。先ほどと手順は同じです。

shell(Cloud9)
$ cd ~/.ssh
$ ssh-keygen -t rsa
Enter file in which to save the key ():ec2_git_rsa
Enter passphrase (empty for no passphrase):何もせずエンター
Enter same passphrase again:何もせずエンター

公開鍵の方はコピーしておきます。

GitHubに公開鍵を登録する

ここも先ほどと手順は同じです。

GitHubにログイン
→ 右上アイコンから『Settings』 → 『SSH and GPG keys』 → 『New SSH key』

Title:hoge
Key:コピーした公開鍵
『Add SSH key』

SSHの設定をする

SSHのconfigを触ります。
クライアント側とサーバー側どちらも設定を変更します。

クライアント

Cloud9
$ vim ~/.ssh/config
~/.ssh/config
Host lantern_key_2_rsa
  Hostname 設定したElastic IP
  Port 22
  User 作成したユーザー名
  IdentityFile ~/.ssh/lantern_key_rsa

Host ec2_git_rsa
  Hostname github.com
  User git
  IdentityFile ~/.ssh/ec2_git_rsa

ホストサーバー

server
$ vim ~/.ssh/config
~/.ssh/config
Host github
  Hostname github.com
  User git
  ForwardAgent yes

ForwardAgentをyesにすることで、クライアント側の鍵を流用することができます。

ssh-agentに鍵を加える+自動化する

ssh-agentに鍵を加えます。
ここに鍵を加えることで、サーバーからGitHubに繋ぐことができます。

しかしssh-agentは登録した鍵がログインごとにリセットされます。
よってログイン時に自動で鍵を加えるようにします。

~/.bash_profile
echo "Add EC2 and GitHub keys to ssh-agent"
eval `ssh-agent`

HOST_KEY='lantern_key_2_rsa'
GIT_KEY='ec2_git_rsa'

ssh-add $HOME/.ssh/$HOST_KEY
ssh-add $HOME/.ssh/$GIT_KEY

ログアウト時にssh-agentを停止させる処理も加えます。

~/.bash_logout
eval `ssh-agent -k`

サーバーからGitHubに接続できるか確認する

それでは本当に接続できる確認します。

Cloud9
$ ssh -A lantern_key_rsa

GitHubへの接続には-Tオプションを使用します。
これによってクライアント側の鍵を流用します。

server
$ ssh -T github
Hi ユーザー名! You've successfully authenticated, but GitHub does not provide shell access.

サーバーの秘密鍵などを削除する

あとはサーバー側の秘密鍵を削除します。
GitHubの古い公開鍵も必要ないので、こちらも削除します。

省略

アプリケーションをデプロイする

後はデプロイするだけです。

Cloud9
$ cap production deploy

ブラウザでEC2のIPを検索し、アプリケーションが表示されたら成功です。
(しかしエラーなしでここまで来るのは奇跡です。解決策は後述します。)

トラブルシューティング

自動デプロイする際、様々なエラーが発生します。
一例ですが、私が見舞ったトラブルの解決策を書き残します。

Permission denied (publickey).

主にSSH接続に失敗するとこのエラーが発生します。

解決策1:ssh-agentを確認する

ssh-agentに鍵が追加されていないから認証できないケースです。

Cloud9
$ ssh-add -l
The agent has no identities.

このような文章が出てきた場合、キーが追加されていません。
キーを追加しましょう。

$ ssh-add キーのパス

参考になりました↓
SSH で Permission Denied となる傾向と対策

解決策2:サーバーの容量を確認、削除する

容量がいっぱいになって起動がうまくいかなくなったケースです。
適宜、削除します。

server
$ cd /var/www/アプリ名/releases
$ ls
2020XXXXXXXXXX 2020XXXXXXXXXX 2020XXXXXXXXXX(...他)
$ rm -rf 2020XXXXXXXXXX (...他)

Your Ruby version is X.X.X, but your Gemfile specified X.X.X

クライアント側とサーバー側でのバージョンの不一致です。

解決策1:クライアント側とサーバー側のバージョンを合わせる

それぞれのRubyのバージョンを合わせます。
Cloud9の場合、Rubyのパッケージ管理にはrvmが使われているはずです。

Cloud9
$ ruby -v
$ rvm list
# バージョンを違っていた場合、インストールする
$ rvm install X.X.X
$ rvm use X.X.X
$ ruby -v

サーバー側は、rbenvを使っています。

server
$ rbenv versions
# バージョンを違っていた場合、インストールする
$ rbenv install X.X.X
$ rbenv global X.X.X
$ ruby -v

バージョンが切り替わっていない場合、一度再起動してみましょう。

解決策2:Gemfileやconfig/deploy.rbを確認する

ファイルでのバージョン指定が間違っている可能性があります。
確認してみましょう。

Gemfile、config/deploy.rbのバージョンを確認する

ActiveRecord::NoDatabaseError: Unknown database 'アプリ名_production'

データベースが作られていないために発生しています。

解決策1:AWS側の設定を整える

クライアント側からRDSに接続できない場合、AWS側の設定を疑います。

VPC
AWSにログイン → AWSマネジメントコンソール『VPC』
画面左のダッシュボード『VPC』 → 作成したVPCを選択 → 『アクション』 → 『DNSホスト名の編集』

DNSホスト名:有効化にチェック
『保存』

セキュリティグループ
画面左のダッシュボード『セキュリティグループ』 → 作成したセキュリティグループを選択 → 下部タブ『インバウンドのルール』 → 『ルールの編集』

タイプ:MySQL/Aurora
ソース:カスタム、0.0.0.0/0
『ルールの保存』

RDS
AWSマネジメントコンソール『RDS』
画面左のダッシュボード『データベース』 → 作成したデータベースを選択 → 『変更』

パブリックアクセシビリティ:はい
『次へ』
『DBインスタンスの変更』

参考になりました↓
AWS Aurora でDB作成時に「 Cannot create a publicly accessible DBInstance. The specified VPC does not support DNS resolution, DNS hostnames, or both. Update the VPC and then try again」とエラーになった際の対処法
[備忘録] RDSで外部サーバからアクセス許可する方法

解決策2:プロダクション用のデータベースを作る

デプロイ前に本番用のデータベースを作成します。

Cloud9
$ rails db:create RAILS_ENV=production

500 Internal Server Error

cap production deployは済んだものの、何らかの理由で処理が完了しない場合に起こります。

解決策:シンボリックリンクのフォルダを確認する

正しくシンボリックリンクが設定されていない場合があります。
例えば以下のように、フォルダを追加します。

config/deploy.rb
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system", "public/upload"

Aws::Sigv4::Errors::MissingCredentialsError: Cannot load `Rails.config.active_storage.service`:

pumaのエラーログから、Credentialsのエラーです。
Rails5.2以上をお使いの場合、後述の参考記事を一読すると良いでしょう。
とりあえず解決策を載せておきます。

解決策:Credentialsを確認する

Cloud9
$ EDITOR=vim rails credentials:edit
credentials
# 以下のコメントアウトを外す
aws:
  access_key_id: XXXX
  secret_access_key: XXXX

あとは先述の『本番環境時のシークレットキーを有効にする』をご確認ください。

参考になりました↓
Rails5.2から導入されたcredentials.yml.encを極める
unicornの.socketファイルがうまく生成されません

Nginxを再起動していない

Nginxを再起動しないため、設定が更新されていない場合があります。
設定し直す度に、再起動を行うことをおすすめします。

解決策:Nginxを再起動、動作を確認する

Nginxでよく使うものを列挙しました。
Nginxの動作確認や、再起動の手順を載せます。

server
# Nginxを停止する
$ sudo systemctl stop nginx
# Nginxを起動する
$ sudo systemctl start nginx
# Nginxの動作確認
$ sudo systemctl status nginx.service
# Nginxのプロセスが使用しているポートを確認する
$ sudo lsof -i | grep nginx
# Nginxの実行中プロセスを確認する
$ ps aux | grep nginx
# Nginxを停止する(何らかの理由で停止できない場合はこちらを使う)
$ sudo kill -9 XXXX

ブラウザで表示されない、301になる

「NginxもPumaも正常に動いている、ログも問題ない」
にも関わらずブラウザで表示されない場合は、Rails側の問題かもしれません。
chromeから「このサイトにアクセスできません」と出る場合、curlで確認します。

shell
$ curl -I http://ホスト側のIPアドレス
HTTP/1.1 301 Moved Permanently
Server: nginx/1.16.1
Date: Wed, 01 Jan 2020 00:00:00 GMT
Content-Type: text/html
Connection: keep-alive
Location: https://ホスト側のIPアドレス/

解決策:config.force_ssl = falseにする

デフォルトではsslを強制しています。
これをfalseにして、httpでの通信ができるようにします。

config/environment/production.rb(Cloud9)
config.force_ssl = false

参考になりました↓
(デプロイ編②)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで


前回:#17 VPC環境構築編
番外:#17.5 MySQL導入編
次回:#18.5 環境変数, Gmail送信設定編

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5