🌊
Rails6 + EC2(Amazon Linux2) + RDS + Puma + Nginx の環境構築
株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。
EC2のサーバーで表題の環境構築を行った際の備忘録を残しておきます。
VPCやサブネットなどのAWSコンソールなどの設定に関しては出てきませんのでご注意ください。
環境について
- Ruby:v2.7.3
- Ruby on Rails:v6.0.3
- Webサーバー:Nginx
- アプリケーションサーバー:Puma v4.3.8(諸々の関係でv4系を利用)
- Redis(sidekiqで利用):v4.0.3
- AWSLogs(ログの収集)
環境構築
EC2でログインユーザー発行
bash
# サーバーへec2-userでログインする
ssh -i <pemファイル> ec2-user@ec2-0-0-0-0.ap-northeast-1.compute.amazonaws.com #パブリック IPv4 DNSに記載されている文字列 or 設定したIPアドレス
bash
sudo su #rootユーザーになる
yum update #パッケージのアップデート
useradd <ユーザー名> #ユーザー名のユーザーを作成
passwd <ユーザー名> #ユーザーに対してパスワードを設定
ログインユーザーに対してsudo権限の付与
bash
visudo
bash
#root ALL=(ALL) ALLと記載されている下に記載
<ユーザー名> ALL=(ALL) ALL
#sudoをパスワードなしで実行したい場合には以下のように記載
<ユーザー名> ALL=(ALL) NOPASSWD: ALL
作成したユーザーになるために、以下のコマンドを実行
bash
exit
su <ユーザー名>
cd ~/
ユーザーでのSSHログインを可能にする
.sshフォルダを作成して権限を付与する。
bash
mkdir ~/.ssh
chmod 700 ~/.ssh/
以下のコマンドは自身のPC(Macの場合)にて実行し、id_rsa.pubのキーをコピーする
bash
pbcopy < ~/.ssh/id_rsa.pub
bash
vim ~/.ssh/authorized_keys
# command + v で内容をペースト
chmod 600 ~/.ssh/authorized_keys #権限を変更しないとsshログインの際に弾かれる
exit #<ユーザー名>からログアウト
exit #サーバーからログアウト
SSHログインでの接続可能時間の変更
通常のままだとSSHログインしている際に、何もしないとすぐに接続が切れるのでそれを長くする。
bash
ssh <ユーザー名>@<IPアドレス>
sudo vim /etc/ssh/sshd_config
sshd_config
#ClientAliveInterval 0
#ClientAliveCountMax 3
上記のような記述があるので以下のように変更して保存
ClientAliveInterval 60
ClientAliveCountMax 120
設定を読み込むためsshdを再起動
bash
sudo systemctl restart sshd
サーバーのタイムゾーンを変更する(必要があれば)
bash
sudo timedatectl set-timezone Asia/Tokyo
Railsアプリケーションに必要なパッケージのインストール
bash
sudo yum install git bzip2 readline-devel zlib-devel gcc libyaml-devel libffi-devel gdbm-devel ncurses-devel gcc-c++ mysql-devel ImageMagick ImageMagick-devel
ruby-build, rbenvのインストール
bash
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
vim ~/.bash_profile
以下の記述を追記
bash
export PATH=$HOME/.rbenv/bin:$PATH
eval "$(rbenv init -)"
bash
source ~/.bash_profile
Ruby, Bundlerのインストール
bash
rbenv install 2.7.3 #時間がかかるので気長に待つ
rbenv rehash
rbenv global 2.7.3
gem install bundler:1.17.1
nvm, NodeJsのインストール
bash
git clone https://github.com/creationix/nvm.git ~/.nvm
vim ~/.bashrc
以下の記述を追記
bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
bash
source ~/.bashrc
nvm install v6.17.1
npm install -g yarn
Nginxのインストール
bash
sudo amazon-linux-extras install nginx1
sudo vim /etc/nginx/conf.d/rails.conf
以下の内容を記述
rails.conf
client_max_body_size 2G;
upstream app_server {
server unix:///var/www/<アプリケーション名>/tmp/sockets/puma.sock;
# capistranoのデプロイでは以下のようになる
# server unix:///var/www/<アプリケーション名>/current/tmp/sockets/puma.sock;
}
server {
listen 80;
server_name <IPアドレス>;
keepalive_timeout 5;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
root /var/www/<アプリケーション名>/public;
# capistranoのデプロイでは以下のようになる
# root /var/www/<アプリケーション名>/current/public;
location ^~ /assets/ {
gzip_static on;
add_header Cache-Control public;
}
try_files $uri/index.html $uri @app_server;
location @app_server {
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
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 {
}
location = /sitemap.xml.gz {
}
location = /robots.txt {
}
location = /favicon.ico {
}
}
sudo systemctl start nginx
Redisのインストール(Sidekiq利用のため)
bash
sudo amazon-linux-extras install redis4.0
sudo systemctl start redis
サーバーからGitHubへの接続
キーの作成
bash
ssh-keygen
# すべてEnterで実行する
cat ~/.ssh/id_rsa.pub
# 出てきた文字列を command + Cでコピー
以下はgithub.comで作業
- GitHubでアプリケーションのリポジトリに遷移
- アプリケーションのリポジトリで Settings > Deploy keys > Add deploy key
- 「title」に適切な名前を入れ、「Key」に先ほどの文字列を貼り付け
- アプリケーションリポジトリのホームに行きsshでのインストールURLをコピー
bash
ssh -T git@github.com
# Hi 〇〇 You've successfully authenticated, but GitHub does not provide shell access. と表示されたらOK
Railsアプリケーションの配置
bash
sudo mkdir -p /var/www
sudo chmod -R 755 /var/www
sudo chown -R <ユーザー名>:<ユーザー名> /var/www
cd /var/www
git clone <先ほどコピーしたsshでのインストールURL>
Railsアプリケーションの設定
bash
cd <アプリケーション>
bundle install
vim config/database.yml
本番環境の設定を記述
database.yml
production:
<<: *default
adapter: mysql2
encoding: utf8
reconnect: false
database: <アプリケーション名>_production
pool: 5
username: <RDSで設定したユーザー名>
password: <RDSで設定したパスワード>
socket: /var/lib/mysql/mysql.sock
host: <RDSのホスト>
bash
bundle exec rails db:create RAILS_ENV=production
bundle exec rails db:migrate RAILS_ENV=production
アセットのコンパイル
bash
bundle exec rails assets:precompile RAILS_ENV=production
Pumaの設定
環境ごとにPumaの設定を読み込みたいためファイルを作成
bash
vim config/puma/production.rb
以下の記述して保存する。
production.rb
# bind "unix://#{Rails.root.join('tmp/sockets/puma.sock')}"だとpumactlコマンドで読み込まないため絶対パスで指定
root_dir = '/var/www/<アプリケーション名>'
max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 5)
min_threads_count = ENV.fetch('RAILS_MIN_THREADS', max_threads_count)
threads min_threads_count, max_threads_count
worker_timeout 60
bind "unix://#{root_dir}/tmp/sockets/puma.sock"
environment 'production'
pidfile File.expand_path('tmp/pids/server.pid')
stdout_redirect File.expand_path('log/puma_access.log'), File.expand_path('log/puma_error.log'), true
# workerの数は適宜変更する。指定しない場合はsingle modeとなるが、指定した場合はcluster modeとなる。
workers 2
plugin :tmp_restart
daemonize
Pumaの起動
bash
bundle exec rails s -e production
# このコマンドでconfig/puma/production.rbを参照してくれる
AWSLogsの設定
bash
sudo yum install awslogs
sudo vim /etc/awslogs/awscli.conf
以下の内容を記述して保存。
bash
[plugins]
cwlogs = cwlogs
[default]
region = ap-northeast-1 #利用しているリージョンに変える
bash
sudo vim /etc/awslogs/awslogs.conf
bash
[/var/log/nginx/access.log]
datetime_format = %Y-%m-%dT%H:%M:%S.%f
file = /var/log/nginx/access.log
buffer_duration = 5000
log_stream_name = nginx_access_log
initial_position = start_of_file
log_group_name = production_nginx_access.log
[/var/log/nginx/error.log]
datetime_format = %Y-%m-%dT%H:%M:%S.%f
file = /var/log/nginx/error.log
buffer_duration = 5000
log_stream_name = nginx_error_log
initial_position = start_of_file
log_group_name = production_nginx_error.log
[/var/www/<アプリケーション名>/log/sidekiq.log]
datetime_format = %Y-%m-%dT%H:%M:%S.%f
file = /var/www/<アプリケーション名>/log/sidekiq.log
buffer_duration = 5000
log_stream_name = sidekiq_log
initial_position = start_of_file
log_group_name = production_sidekiq.log
[/var/www/<アプリケーション名>/log/production.log]
datetime_format = %Y-%m-%dT%H:%M:%S.%f
file = /var/www/<アプリケーション名>/log/production.log
buffer_duration = 5000
log_stream_name = production_log
initial_position = start_of_file
log_group_name = production_production.log
[/var/www/<アプリケーション名>/log/puma_access.log]
datetime_format = %Y-%m-%dT%H:%M:%S.%f
file = /var/www/<アプリケーション名>/log/puma_access.log
buffer_duration = 5000
log_stream_name = puma_access_log
initial_position = start_of_file
log_group_name = production_puma_access.log
[/var/www/<アプリケーション名>/log/puma_error.log]
datetime_format = %Y-%m-%dT%H:%M:%S.%f
file = /var/www/<アプリケーション名>/log/puma_error.log
buffer_duration = 5000
log_stream_name = puma_error_log
initial_position = start_of_file
log_group_name = production_puma_error.log
[/var/log/redis/redis.log]
datetime_format = %Y-%m-%dT%H:%M:%S.%f
file = /var/log/redis/redis.log
buffer_duration = 5000
log_stream_name = redis_log
initial_position = start_of_file
log_group_name = production_redis.log
また、AWSでEC2に対してCloudWatchのアクセス権を付与する。
詳細は以下の記事にて書かれているので参照してください。
bash
sudo systemctl start awslogsd
サーバー再起動後のアプリケーション立ち上げ
サーバーを再起動した場合に、アプリケーションが自動で立ち上がる設定もすることができます。
以下の記事を参考にしてみてください。
Discussion