LoginSignup
5
3

More than 5 years have passed since last update.

AWSのEC2でUbuntu+nginx+Unicornの環境構築物語

Last updated at Posted at 2017-04-02

なれそめ

  • サーバ構築、フレームワークの導入に慣れよう
  • ウェブサービスを自分一人で作れるようになるための練習

概要

  • 自分が慣れるため、今後のメモのためという意味合いが強いです
  • unicornとしての機能には触れません

環境

  • Ubuntu 16.04.2 LTS
  • nginx/1.10.0 (Ubuntu)
  • ruby 2.4.0p0
  • rbenv 1.1.0
  • Bundler version 1.14.6
  • unicorn 5.2.0

1.サーバ初期設定

  1. AWSでEC2インスタンス作成(Ubuntuを選択)
  2. セキュリティグループ設定:自分の利用する回線(送信元)で、指定したポートでSSH接続するために解放する(任意のポート)
  3. AWSで接続のコマンドを用意してくれるのでそれを利用してターミナルからSSHでアクセス
ssh接続の設定

セキュリティを最低限強くするため、22番での接続を禁止し、rootでのログインも禁止する

$ sudo vim /etc/ssh/sshd_config
Port 55555 // 任意のポート番号に変更
PermitRootLogin no // noに変更
$ sudo /etc/init.d/ssh restart

これで22番ポートでのログインが禁止され、以下のようにポートを指定してログインができる

sudo ssh -p 55555 -i "key.pem" ubuntu@ec2-XX-XXX-XXX-XXX.us-west-2.compute.amazonaws.com

sshの設定を変更したらrestartして反映させる

作業ユーザ設定

sudo権限も付与しておく

$ sudo useradd -m sasaki
$ sudo passwd sasaki
$ sudo usermod -G sudo sasaki
$ su - sasaki

2.bundler導入とrailsプロジェクト作成

  1. ruby用ライブラリ(gem)の管理するためにbundlerを用いる
  2. gemコマンドでbundlerをインストール
  3. Gemfileを編集してrailsのインストールの準備
$ sudo apt update
$ sudo apt-get install bundler
$ mkdir rails-app/ && cd rails-app/
$ bundle init
$ vi Gemfile
# A sample Gemfile
source 'https://rubygems.org'

gem 'rails', '>= 5.0.0.1'
gem 'sqlite3'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'therubyracer', platforms: :ruby
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 2.0'
gem 'sdoc', '~> 0.4.0', group: :doc
gem 'bcrypt', '~> 3.1.7'
gem 'unicorn'

group :development, :test do
  gem 'byebug'
  gem 'web-console', '~> 2.0'
  gem 'spring'
end
$ bundle install --path vendor/bundle
$ bundle exec rails new .

ここで僕はsqlite3がないよと怒られたのでapt-getで入れました

$ sudo apt-get install libsqlite3-dev

3.rubyとrbenvの用意

$ cd ~/rails-app/
$ git clone https://github.com/sstephenson/rbenv.git .rbenv
$ git clone https://github.com/sstephenson/ruby-build.git .rbenv/plugins/ruby-build
$ sudo apt update
$ vi ~/.bashrc


```.bashrc
+ [[ -d ~/rails-app/.rbenv  ]] && \
+   export PATH=${HOME}/rails-app/.rbenv/bin:${PATH} && \
+   eval "$(rbenv init -)"
$ source ~/.bashrc

4.アプリケーション作成へ

$ cd ~/rails-app/
$ bundle exec rails generate scaffold board title:string text:string

ここでエラーが発生、よく出るエラーところらしい
エラーが出たら以下のようにコメントアウトを外すして改めてbundle installすると成功うまく行く場合が多い

$ vi Gemfile
- # gem 'therubyracer', platforms: :ruby
+ gem 'therubyracer', platforms: :ruby
$ bundle install
$ bundle exec rails generate scaffold board title:string text:string

rakeコマンドが使えるのでrakeでDBのマイグレート

$ rake db:migrate
$ vi config/routes.rb
routes.rb
...
+  root "boards#index"
end
...

以下のコマンドでサーバを起動(ctrl+C)でキャンセルできる

$ bundle exec rails server -b 0.0.0.0

他にもタブを開いて確認して見ると確認ができる

$ ps aux | grep 0.0.0.0:3000
sasaki  24821  1.0  7.2 751628 73444 pts/1    Sl+  04:27   0:01 puma 3.8.2 (tcp://0.0.0.0:3000) [rails-app]

5.unicorn設定

unicorn.rbについては
ここのを参考にした

$ cd ~/rails-app/config/ && vi unicorn.rb
unicorn.rb
# -*- coding: utf-8 -*-
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true  # 更新時ダウンタイム無し

listen File.expand_path('/tmp/sockets/unicorn.pid', __FILE__)
pid File.expand_path('/tmp/pids/unicorn.pid', __FILE__)
listen "/tmp/sockets/unicorn.sock"
pid "/tmp/pids/unicorn.pid"

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

# ログの出力
stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])

rakeコマンドでユニコーンの起動や停止を行うために以下の編集を行う
こちらも先ほどのQiitaを参考にしました

$ bundle exec rails generate task unicorn
$ cd ~/rails-app/ && vi lib/tasks/unicorn.rake
unicorn.rake
namespace :unicorn do
  ##
  # Tasks
  ##
  desc "Start unicorn for development env."
  task(:start) {
    config = Rails.root.join('config', 'unicorn.rb')
    sh "bundle exec unicorn_rails -c #{config} -E development -D"
  }

  desc "Stop unicorn"
  task(:stop) { unicorn_signal :QUIT }

  desc "Restart unicorn with USR2"
  task(:restart) { unicorn_signal :USR2 }

  desc "Increment number of worker processes"
  task(:increment) { unicorn_signal :TTIN }

  desc "Decrement number of worker processes"
  task(:decrement) { unicorn_signal :TTOU }

  desc "Unicorn pstree (depends on pstree command)"
  task(:pstree) do
    sh "pstree '#{unicorn_pid}'"
  end

  def unicorn_signal signal
    Process.kill signal, unicorn_pid
  end

  def unicorn_pid
    begin
      File.read("/tmp/pids/unicorn.pid").to_i
    rescue Errno::ENOENT
      raise "Unicorn doesn't seem to be running"
    end
  end
end

これで以下のようなコマンドが使える

rake unicorn:start
rake unicorn:stop

6.nginx導入とブラウザで確認

$ sudo apt-get install -y nginx
$ /etc/init.d/nginx start
$ /etc/init.d/nginx status

これでnginxが Active: active (running) であることを確認できるはず

nginxとのやりとりにはソケットを使う
conf.dにconfファイルを置けばそれが読まれる設定になっている

$ cd /etc/nginx/conf.d/
$ sudo vi local.conf
local.conf
upstream unicorn {
  server unix:/tmp/sockets/unicorn.sok;
}

server {
  listen 80 default_server;
  server_name localhost-rails;

  access_log /var/log/nginx/sample_access.log;
  error_log /var/log/nginx/sample_error.log;

  root /home/sasaki/rails-app/app/views/boards;

  client_max_body_size 100m;
  error_page 404 /404.html;
  error_page 500 502 503 504 /500.html;
  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_pass http://unicorn;
  }
}
$ sudo vi ../nginx.conf
nginx.conf
- include /etc/nginx/sites-enabled/*;
+ # include /etc/nginx/sites-enabled/*; 

以下のようにそれぞれのファイルで同じ場所のsockファイルを見るように設定されていることが必要
違ってたら揃える

/etc/nginx/conf.d/local.conf
server unix:/tmp/sockets/unicorn.sock;
unicorn.rb
listen "/tmp/sockets/unicorn.sock"
pid "/tmp/pids/unicorn.pid"

sockファイルの置き場は工夫の余地があるかと
AWSを用いているのでブラウザから見れるようにセキュリティグループに追加し
nginx再起動させてhttp://でアクセス

$ /etc/init.d/nginx restart

うまくいかないとき

nginxのログ(上記の設定だと)

$ sudo tail -f /var/log/nginx/sample_access.log
$ sudo tail -f /var/log/nginx/sample_error.log
5
3
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
5
3