TECH EXPERT 45日目

TECH::EXPERT

git error 128が出たり、carrierwave導入でundefined const fogが出たりで何一つ進まなかった1日でした。デプロイって怖い。
credentials.ymlがエンコードされてるのでmaster.keyがなかったり、チーム開発の怖さを知ったよ。とりあえずdeployのとりあえずすら動かないとは。

デプロイ

Amazon Linux 2AMIでなく、Amazon Linux AMI で作成

秘密キーをダウンロード(もしくは既存のキーを使う)

新しいEIPの割り当てボタン(要はIPの取得)

アクションからアドレスの関連付け
プライベートIPはなにも入力しない。
関連付けさせると自動で設定される。

セキュリティグループからインバウンドを選択し、ポートの開放

タイプを「HTTP」、プロトコルを「TCP」、ポート範囲を「80」、送信元を「カスタム / 0.0.0.0, ::/0」に設定します。「0.0.0.0」や「::/0」は「全てのアクセスを許可する」という意味です。

~/.sshへ移動してsshでインスタンスへ接続

ssh -i 秘密キー名.pem ec2-user@elastic-ipアドレス

必要なパッケージのダウンロード

sudo yum update
sudo yum install \
git make gcc-c++ patch \
libyaml-devel libffi-devel libicu-devel \
zlib-devel readline-devel libxml2-devel libxslt-devel \
ImageMagick ImageMagick-devel \

openssl-develというRubyのインストールに必要なパッケージをインストール

sudo yum install -y openssl-devel

node.jsのインストール

sudo curl -sL https://rpm.nodesource.com/setup_6.x | sudo bash -
sudo yum install nodejs

rbenvとruby-buildをインストール

#rbenvのインストール
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
#パスを通す
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
#rbenvを呼び出すための記述
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
#.bash_profileの読み込み
source .bash_profile
#ruby-buildのインストール
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
#rehashを行う
rbenv rehash

Rubyをインストール
ローカルと同じバージョンのrubyをインストール。

rbenv install 2.5.1
rbenv global 2.5.1
rbenv rehash  #rehashを行う
ruby -v # バージョンを確認

mySQLのインストール

バージョン5.6をインストール

sudo yum install mysql56-server mysql56-devel mysql56

MySQLを起動

sudo service mysqld start

起動の確認

sudo service mysqld status

パスワードの設定

sudo /usr/libexec/mysql56/mysqladmin -u root password '設定したいパスワード'

mysqlへ接続

mysql -u root -p

githubにインスタンスのキーを登録してssh接続

キーを作成。パスフレーズ等は無視してenterでok

ssh-keygen -t rsa -b 4096

以下にキーが保存されるのでキーを開いて、値をgithubに登録

cat ~/.ssh/id_rsa.pub

githubに接続できるか確認。

ssh -T git@github.com

以下のように表示されたらOK

Hi ユーザー名! You've successfully authenticated, but GitHub does not provide shell access.

Unicornをインストール

ローカルで以下を記入してbundle install

group :production do
  gem 'unicorn', '5.4.1'
end

server side

以下を作成

/var/www/project名

git clone

sudo mkdir /var/www/
sudo chown ec2-user /var/www/
cd /var/www/
git clone https://github.com/<レポジトリ名>.git

環境変数の設定

プロジェクトフォルダで

rake secret

環境変数への書き込み

sudo vim /etc/environment
DATABASE_PASSWORD='MySQLのrootユーザーのパスワード'
SECRET_KEY_BASE='先程コピーしたsecret_key_base'

適応するため、一旦exit。再度SSHで接続。

portの開放

セキュリティグループ、インバウンド、編集から以下を追加

カスタム TCP ルールTCP30000.0.0.0/0

unicornの起動

unicorn_rails -c config/unicorn.rb -E production -D

エラーログを参照。

less log/unicorn.stderr.log
注)ユニコーンはDBがないので起動しない。

config/database.yml(ローカル)を編集して以下のように。

production:
  <<: *default
  database: ~~~(それぞれのアプリケーション名によって異なっています。こちらは編集しないでください)
  username: root
  password: <%= ENV['DATABASE_PASSWORD'] %>
  socket: /var/lib/mysql/mysql.sock

サーバーで

 git pull origin master
rails db:create RAILS_ENV=production
rails db:migrate RAILS_ENV=production

unicornの起動

unicorn_rails -c config/unicorn.rb -E production -D

アセットコンパイル

rails assets:precompile

ユニコーンkill

ps aux | grep unicorn
kill -9 <確認したunicorn rails masterのPID>

ユニコーンリスタート
RAILS_SERVE_STATIC_FILES=1 という指定を先頭に追加してください。これは、コンパイルされたアセットをRailsが見つけられるような指定

RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D

nginx

homeディレクトリで以下

sudo yum install nginx
sudo vim /etc/nginx/conf.d/rails.conf

上のファイルを以下のように編集

upstream app_server {
  # Unicornと連携させるための設定。アプリケーション名を自身のアプリ名に書き換えることに注意。今回であればおそらくchat-space
  server unix:/var/www/<アプリケーション名>/tmp/sockets/unicorn.sock;
}

# {}で囲った部分をブロックと呼ぶ。サーバの設定ができる
server {
  # このプログラムが接続を受け付けるポート番号
  listen 80;
  # 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない
  server_name <Elastic IP>;

# 接続が来た際のrootディレクトリ
  root /var/www/<アプリケーション名>/public;

# assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定
  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    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;
}

POSTメソッドでもエラーが出ないようにするために、下記のコマンドも実行

cd /var/lib
[ec2-user@ip-172-31-25-189 lib]$ sudo chmod -R 775 nginx  
sudo service nginx restart

capistrano

uglifterを無効化。プリコンパイルエラーの原因

# config.assets.js_compressor = :uglifier

gem bundle install

group :development, :test do
  gem 'capistrano'
  gem 'capistrano-rbenv'
  gem 'capistrano-bundler'
  gem 'capistrano-rails'
  gem 'capistrano3-unicorn'
end

設定ファイルの生成

bundle exec cap install

capfileを以下のように編集

require "capistrano/setup"
require "capistrano/deploy"
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'

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

config/deploy/production.rbを以下のように編集

server '<用意したElastic IP>', user: 'ec2-user', roles: %w{app db web}

config/deploy.rbを以下のように編集

# config valid only for current version of Capistrano
# capistranoのバージョンを記載。固定のバージョンを利用し続け、バージョン変更によるトラブルを防止する
lock '<Capistranoのバージョン>'

# Capistranoのログの表示に利用する
set :application, '自身のアプリケーション名'

# どのリポジトリからアプリをpullするかを指定する
set :repo_url,  'git@github.com:<Githubのユーザー名>/<レポジトリ名>.git'

# バージョンが変わっても共通で参照するディレクトリを指定
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')

set :rbenv_type, :user
set :rbenv_ruby, '<このアプリで使用しているrubyのバージョン>' #カリキュラム通りに進めた場合、2.5.1か2.3.1です

# どの公開鍵を利用してデプロイするか
set :ssh_options, auth_methods: ['publickey'],
                  keys: ['<ローカルPCのEC2インスタンスのSSH鍵(pem)へのパス>']  ※例:~/.ssh/key_pem.pem

# プロセス番号を記載したファイルの場所
set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }

# Unicornの設定ファイルの場所
set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
set :keep_releases, 5

# デプロイ処理が終わった後、Unicornを再起動するための記述
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end

unicorn.rbを以下のように編集

app_path = File.expand_path('../../', __FILE__)

worker_processes 1

working_directory app_path
pid "#{app_path}/tmp/pids/unicorn.pid"
listen "#{app_path}/tmp/sockets/unicorn.sock"
stderr_path "#{app_path}/log/unicorn.stderr.log"
stdout_path "#{app_path}/log/unicorn.stdout.log"

 ↓↓↓↓↓↓↓ 以下のように変更 ↓↓↓↓↓↓

# ../が一つ増えている
app_path = File.expand_path('../../../', __FILE__)

worker_processes 1
# currentを指定
working_directory "#{app_path}/current"

# それぞれ、sharedの中を参照するよう変更
listen "#{app_path}/shared/tmp/sockets/unicorn.sock"
pid "#{app_path}/shared/tmp/pids/unicorn.pid"
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"

nginxの設定ファイルを編集

sudo vim /etc/nginx/conf.d/rails.conf
upstream app_server {
  server unix:/var/www/<アプリケーション名>/tmp/sockets/unicorn.sock;
}
      
 ↓↓↓↓↓↓↓ 以下のように変更 ↓↓↓↓↓↓

upstream app_server {
  server unix:/var/www/<アプリケーション名>/shared/tmp/sockets/unicorn.sock;
}
root /var/www/<アプリケーション名>/public;
      
 ↓↓↓↓↓↓↓ 以下のように変更 ↓↓↓↓↓↓

root /var/www/<アプリケーション名>/current/public;
location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }
      
 ↓↓↓↓↓↓↓ 以下のように変更 ↓↓↓↓↓↓

location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    root   /var/www/<アプリケーション名>/current/public;
  }

nginxの再起動

sudo service nginx reload
sudo service nginx restart

mysqlの再起動

sudo service mysqld restart

ユニコーンのkill

kill -QUIT `cat tmp/pids/unicorn.pid`

ローカルでデプロイ!

bundle exec cap production deploy

コメント