はじめに
EC2にRails環境を構築、Capistranoで自動デプロイするための初期設定を紹介していきます。
主に個人開発やテスト環境で扱う最低限の設定のみ記載します。
コピペで大体できるはず、、!
環境
OS : Amazon Linux 2
Webサーバー : Nginx
アプリケーションサーバー : puma
メールサーバー : postfix
DB : RDS(MySQL)
前提
macOS
AWSにてEC2、RDSを構築済み
EC2に接続
"sudo ssh -i [keyペアファイル] ec2-user@[パブリックIP]"
# 確認が出るので "yes"
# PCのパスワードを要求されるので、入力。
初期設定
- yumをアップデート
yumをまとめてアップデート
$ sudo yum update -y
yum cromインストール
$ sudo yum install -y yum-cron
EPELを有効化
$ sudo amazon-linux-extras install epel
セキュリティのみ自動でパッチがあたるようにcronの設定ファイルを変更します。
$ vi /etc/yum/yum-cron.conf
変更点
update_cmd = security
apply_updates = yes
email_to = [任意]
設定したら起動及び再起動自動の自動実行を設定
$ systemctl start yum-cron
$ systemctl enable yum-cron
- タイムゾーンを日本時間に変更します。
タイムゾーンをJSTに設定
$ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
タイムゾーンがJSTに変更されたか確認
$date
/etc/sysconfig/clockの設定変更を変更
$ sudo vi /etc/sysconfig/clock
以下の内容を変更
ZONE="Asia/Tokyo"
UTC= true
- EC2インスタンスを再起動し、全てのプロセスが新しいタイムゾーンを設定を利用するようにします。
$ sudo reboot
ユーザー追加
セキュリティ強化のため、ec2-userのアカウント名をそのまま使うのではなく、
ec2-userを停止にして、新しいユーザでログインできるようにします。
新規ユーザー作成
$ sudo adduser my-user
wheelグループに追加
$ sudo usermod -G wheel my-user
sudo権限を付与
$ sudo visudo
viが開くので、行末に「my-user ALL=(ALL) NOPASSWD: ALL」を追加
my-user ALL=(ALL) NOPASSWD: ALL
:wqで保存
ec2-userのauthorized_keysをmy-userの.sshディレクトリにコピーし、適切なパーミッションを設定します。
$ sudo rsync -a ~/.ssh/authorized_keys ~my-user/.ssh/
$ sudo chown -R my-user:my-user ~my-user/.ssh
$ sudo chmod 700 ~my-user/.ssh/
$ sudo chmod 600 ~my-user/.ssh/**
SSH接続設定
EC2のシークレットキーをローカルPCの以下に配置
/Users/[ユーザー]/.ssh/***.pem
.sshディレクトリに移動
cd .ssh
シークレットキーを持っている他のユーザーもログインできるように権限を変更
$ chmod 600 ***.pem
権限が変更されているか確認
$ ls -al
-rw------- になっていればOK
configに接続設定を記載
$ vi config
ローカルにショートカットを作成
Host [ホスト名]
HostName [パブリックIP]
Port 22
User my-user
IdentityFile ~/.ssh/***.pem
:wqで保存
my-userで接続できるか確認します。
$ ssh [ホスト名]
接続できたら、rootになれるか確認
$ sudo su -
SSHのセキュリティ設定
rootとec2-userでのSSHを禁止する
$ sudo vi /etc/ssh/sshd_config
以下を追加
# ec2-userでのログインを禁止
DenyUsers ec2-user
# 暗号化アルゴリズムの指定
Ciphers aes128-ctr,aes192-ctr,aes256-ctr
# 鍵付きハッシュのアルゴリズム
MACs hmac-sha2-256,hmac-sha2-512
以下を変更
AuthorizedKeysFile .ssh/authorized_keys
PermitRootLogin no
:wqで保存
設定を反映
$ service sshd reload
RVMとRubyをインストール
Rootに変更
$ sudo su -
RVMをインストール
# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
# curl -sSL https://get.rvm.io | bash
Rubyのインストールに必要なライブラリをインストール
# yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison iconv-devel wget libxml2 libxml2-devel libxslt libxslt-devel
# yum install -y bzip2-devel lcms-devel libjpeg-devel libX11-devel libXt-devel libtiff-devel ghostscript-devel libXext-devel libpng-devel
ImageMagickを使うのでインストール(任意)
# yum install -y ImageMagick ImageMagick-devel
RVMを有効にするために一旦ログアウトし、もう一度SSH接続してrootになります。
Rubyをインストール
今回は2.3.8を使用
# rvm install 2.3
# rvm use 2.3.8
# ruby -v
bundllerをcapistranoが使うのでインストール
# gem install bundler
MySQLをインストール
mariaDB削除
$ sudo yum remove mariadb-libs
$ sudo rm -rf /var/lib/mysql
mysqlインストール
$ sudo yum install mysql
Amazon RDSヘ接続
$ mysql -h {ENDPOINT} -P 3306 -u {Username} –p
パスワードが要求されるので、RDSで設定したパスワードを入力
posfixのインストール
$ sudo yum install postfix
設定ファイルを変更
$ vi /etc/postfix/main.cf
適宜各要素を以下のように変更
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
home_mailbox = Maildir/
smtpd_banner = $myhostname ESMTP unknown
allow_min_user = yes
自動起動設定
$ systemctl enable postfix
$ systemctl start postfix
Nginxをインストール
$ sudo yum -y install nginx
NginxでSSL通信する場合は鍵を配置
$ vi /etc/nginx/conf.d/server.key
サーバー証明書、中間証明書を配置
$ vi /etc/nginx/conf.d/server_geotrustca.crt
自動起動設定
$ systemctl start nginx
$ systemctl enable nginx
設定ファイルの文法チェック
$ nginx -t
redisのインストール
$ rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
$ yum install --enablerepo=epel,remi redis
$ systemctl enable redis
$ systemctl start redis
RailsディレクトリとShared内ファイルの作成
Capistranoのディレクトリ構成に合わせます。
sharedディレクトリを作成
mkdir -p /usr/local/rails/[デプロイするアプリ名]/shared/
mkdir -p /usr/local/rails/[デプロイするアプリ名]/shared/public/assets/
mkdir -p /usr/local/rails/[デプロイするアプリ名]/shared/config
※Webpackerを使う場合、アセットパイプラインでエラーが出る場合は空ファイルを配置
touch /usr/local/rails/[デプロイするアプリ名]/shared/public/assets/.manifest.json
touch /usr/local/rails/[デプロイするアプリ名]/shared/public/assets/.sprockets-manifest.json
secret_key_baseを.envで管理(デモ環境なのでmaster.keyは使わない)
vi /usr/local/rails/[デプロイするアプリ名]/shared/.env
RuntimeErrorになるので、rake secretで生成した文字列を貼り付けます。
bundle exec rake secret
ff9906beb21fd77ca11aa433d42b7caa720f37641a27bf1617e67894a4fca2c64526af874d1ef1cfac4372cabdf18127110b31bb766c46ef35dbab62736b04e3
SECRET_KEY_BASE: ff9906beb21fd77ca11aa433d42b7caa720f37641a27bf1617e67894a4fca2c64526af874d1ef1cfac4372cabdf18127110b31bb766c46ef35dbab62736b04e3
ファイルの所有者を変更
chown -R my-user:my-user /usr/local/rails
※AWS認証情報を扱う場合は参考にしてください(CLI設定がおすすめ)
https://dev.classmethod.jp/cloud/aws/how-to-configure-aws-cli/
node.jsとyarnを使う場合はインストール
node.jsのインストール
$ curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
sudo yum install nodejs
yarnのインストール
$ curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
$ sudo rpm --import https://dl.yarnpkg.com/rpm/pubkey.gpg
$ sudo yum install yarn
Gitの設定
gitをインストール
$ sudo yum -y install git
.sshに移動
$ cd /home/my-user/.ssh
.ssh ディレクトリがない場合は作成し,パーミッションを700に設定
$ mkdir .ssh
$ chmod 700 .ssh
キーペアの登録
$ ssh-keygen
id_rsa id_rsa.pub が生成される
~/.ssh/id_rsa.pubの内容をクリップボードにコピー、GitHubに登録
$ pbcopy < ~/.ssh/id_rsa.pub
authorized_keysに変更
$ mv id_rsa.pub authorized_keys
接続設定を記載
$ vi ~/.ssh/config
Host GitHub
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa
パーミッションを変更
$ chown -R my-user:my-user /home/my-user/.ssh
$ chmod 700 /home/my-user/.ssh/
$ chmod 600 /home/my-user/.ssh/authorized_keys
$ chmod 600 /home/my-user/.ssh/id_rsa
$ chmod 600 /home/my-user/.ssh/config
Capistranoでのデプロイ
参考にさせていただきました。
https://qiita.com/naoki_mochizuki/items/657aca7531b8948d267b
pumaの設定のみ追記しました。
# Capistranoのバージョンを固定
lock '3.11.0'
# アプリケーション名
set :application, "[アプリ名]"
# レポジトリURL
set :repo_url, "ssh://git@github.com:****/[アプリ名].git"
# gitでバージョン管理方法
set :scm, :git
# 対象ブランチ masterに固定(デフォルトはmaster)
set :branch, '[ブランチ名]'
# デプロイ先ディレクトリ フルパスで指定
set :deploy_to, "/usr/local/rails/[アプリ名]"
# sharedに入るものを指定
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets bundle}
# rvmのパス
set :default_env, { rvm_bin_path: '~/.rvm/bin' }
# sudo に必要
set :pty, true
# 1回分のreleasesを保持する(デフォルトは5)
set :keep_releases, 1
# puma設定
set :puma_threds, [4, 16]
set :puma_workers, 0
set :puma_bind, "unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
set :puma_access_log, "#{release_path}/log/puma.error.log"
set :puma_error_log, "#{release_path}/log/puma.access.log"
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, true
SSHKit.config.command_map[:rake] = 'bundle exec rake'
namespace :deploy do
#puma再起動タスク
desc "Restart Puma"
task :restart do
on roles(:app), in: :sequence, wait: 5 do
invoke 'puma:restart'
end
end
after :finishing, 'deploy:cleanup'
end
require "capistrano/setup"
require "capistrano/deploy"
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
require "capistrano/rvm"
# require "capistrano/rbenv"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
EC2サーバーのIP、EC2サーバーにログインするユーザー名、サーバーのロールを記述
server 'パブリックIP', user: 'my-user', roles: %w{app db web}
デプロイするサーバーにsshログインする鍵の情報を記述
set :ssh_options, keys: '~/.ssh/***.pem'
おまけ logのローテーション
$ sudo vi /etc/logrotate.d/[アプリ名]
/usr/local/rails/[アプリ名]/shared/log/*.log {
daily #ログを毎日ローテーションする
missingok #ログファイルが存在しなくてもエラーを出さずに処理を続行
rotate 10 #10世代分古いログを残す
dateext #日次ローテート+日付文字列
compress #ローテーションしたログをgzipで圧縮
sharedscripts #複数指定したログファイルに対し、postrotateで記述したコマンドを実行
su my-user my-user #rotateするユーザを指定
postrotate
puma_pid=/usr/local/rails/[アプリ名]/shared/tmp/pids/puma.pid
test -e $puma_pid && kill -USR2 $(cat $puma_pid) || true
endscript
}
エラーが出ていないか確認
$ logrotate -d /etc/logrotate.d/[アプリ名]