LoginSignup
3
5

More than 5 years have passed since last update.

CentOS 6.8上でApache httpd + UnicornでRailsアプリを動かす

Posted at

前提

とある事情でCentOS6.8上でRailsアプリを動かすことになったので、その時のメモです。

セキュリティについてはあまり考慮していません。具体的にはSE LinuxはOffにし、Apache httpdも全てに対してアクセス許可をしています。

各種バージョン

  • OSはCentOS 6.8 64bit版
  • Apache httpdはyum install httpdで入れたバージョンである2.2です。
  • Rubyは2.3.3
  • Railsは4.2.8

手順

OSの環境構築

railsappグループを作成します。

$ sudo groupadd railsapp

既存のユーザをrailsappグループに属すようにします。例えば、dev1ユーザをrailsappグループに属すようにするには次のようにします。

$ sudo usermod -aG railsapp dev1

EPELのリポジトリをインストールします。

$ sudo yum -y install epel-release

Rubyのインストールに必要な各種ライブラリをインストールします。この情報は、rbenvのpluginであるruby-buildのページに記載があります。

$ sudo yum install -y gcc bzip2 openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel sqlite-devel git

Nodejsのインストールを行います。単にtherubyracerをインストールしたくないためです。これについては、NodejsのWebサイトに記載があります。

$ sudo su -
# curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -
# yum -y install nodejs

Apacheのインストールを行います。

$ sudo yum install -y httpd

SE LinuxをOffにします。まずは設定ファイルである/etc/selinux/configを開きます。

$ sudo vim /etc/selinux/config

SELINUX=enforcingとなっている行をSELINUX=disabledに変更します。


# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

その後、システムを再起動します。

$ sudo reboot

Rubyのインストール

Rubyのインストールはrbenvを使います。特定のユーザではなく、システム全体で使えるようにします。

$ cd /usr/local
$ sudo git clone https://github.com/rbenv/rbenv.git rbenv
$ sudo chgrp -R railsapp rbenv
$ sudo chmod -R g+rwxXs rbenv

環境変数の設定を行います。/etc/profileの末尾に次の記述を追加します。

export RBENV_ROOT=/usr/local/rbenv
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"

書き終わったら、再読込して有効化します。

source /etc/profile

次にruby-buildをインストールします。

$ mkdir /usr/local/rbenv/plugins
$ cd /usr/local/rbenv/plugins
$ sudo git clone https://github.com/rbenv/ruby-build.git
$ sudo chgrp -R railsapp ruby-build
$ sudo chmod -R g+rwxs ruby-build

また、rbenv-default-gemsを入れます。これを入れるとRubyのインストール時に自動的に設定したgemもインストールされます。

$ cd /usr/local/rbenv/plugins
$ git clone https://github.com/rbenv/rbenv-default-gems.git

次に/usr/local/rbenv/default-gemsというファイルを作り、1行に1つのgemを書きます。

bundler
pry

Rubyをインストールします。

$ rbenv install 2.3.3

インストール後、使うRubyのバージョンをglobal設定としておきます。

$ rbenv global 2.3.3

今回Railsは4.2.8を使うので、対象バージョンのRailsをインストールします。

$ gem install rails -v 4.2.8 --no-doc

Railsアプリの作成

動かすRailsアプリを作ります。サンプルなのでテストファイルは作らずに。Gemfileを編集したあとでbundle installするのでrails newのタイミングではbundle installはしないようにします。

$ rails _4.2.8_ new rails_sample -B -T --skip-turbolinks

Gemfileを編集します。development環境やtest環境などのgemは記していません。

source 'https://rubygems.org'

gem 'rails', '4.2.8'
gem 'sqlite3'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'jquery-rails'
gem 'jbuilder', '~> 2.0'

gem 'unicorn'

Gemfileを編集後にbundle installします。

$ bundle install --path vendor/bundle

動作確認のためにrails g scaffoldで適当にアプリを作ります。

$ bundle exec rails g scaffold post title:string body:text
$ bundle exec rake db:migrate RAILS_ENV=production

config/routes.rbを編集してroot pathを設定します。

config/routes.rb
Rails.application.routes.draw do
  resources :posts
  root 'posts#index'
end

JavaScriptやCSSをprecompileします。

$ bundle exec rake assets:precompile

環境変数SECRET_KEY_BASEに設定する値を生成します。

$ bundle exec rake secret

生成した値は、Apache httpdの実行ユーザの環境変数として設定します(下記のxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxの部分はbundle exec rake secretで生成された値を入れます)。

/home/dev1/.bash_profile
export SECRET_KEY_BASE=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Unicornの設定

config/uniorn.rbというファイルを作成します。

config/unicorn.rb
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true  # 更新時ダウンタイム無し

listen 8080, :tcp_nopush => true
pid "/tmp/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'])

これで次のコマンドでUnicornが起動するようになります。

$ bundle exec unicorn_rails -c config/unicorn.rb -E production

rakeコマンドを作り、Unicornの起動や終了ができるようにします。

lib/tasks/unicorn.rake
namespace :unicorn do
  desc "Start unicorn for production env."
  task(:start) {
    config = Rails.root.join('config', 'unicorn.rb')
    sh "bundle exec unicorn_rails -c #{config} -E production -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/unicorn.pid").to_i
    rescue Errno::ENOENT
      raise "Unicorn doesn't seem to be running"
    end
  end

end

これでUnicornはRailsアプリのROOTディレクトリ上で以下のコマンドを実行します。

$ bundle exec rake unicorn:start

で起動することができるようになります。

また、RailsアプリのROOTディレクトリ上で

$ bundle exec rake unicorn:stop

でUnicornの停止ができるようになります。

Apache httpdの設定

Apache httpdの設定ファイルを記述します。管理しやすいように/etc/httpd/conf/httpd.confに追記するのではなく、別ファイルに記述します。

アクセス制御はとりあえず全てに対して許可するようにします。

RailsアプリのROOTディレクトリ上は/home/dev1/work/rails_sampleとした場合、次のような設定となります。

/etc/httpd/conf.d/railsapp.conf
<VirtualHost *:80>
  DocumentRoot /home/dev1/work/rails_sample/public
  <Directory "/home/dev1/work/rails_sample/public">
    AllowOverride All
    Options -MultiViews
    Order deny,allow
    Allow from all
  </Directory>
  ServerName サーバ名
  ErrorLog logs/app-error_log
  CustomLog logs/app-access_log common

  <Proxy *>
    Order deny,allow
  </Proxy>

  ProxyRequests Off

  ProxyPass /assets/ !
  ProxyPass /fonts/ !
  ProxyPass /robots.txt !
  ProxyPass /favicon.ico !

  ProxyPass / http://localhost:8080/
  ProxyPassReverse / http://localhost:8080/
  ProxyPreserveHost on
</VirtualHost>

また、Apache httpdの実行ユーザと実行グループを変更します。

/etc/httpd/conf/httpd.conf
## (前略)
User dev1
Group railsapp
## (後略)

これで後はUnicornの起動とhttpdを起動してブラウザでアクセスすればOKです。

Unicornの起動はRailsアプリのROOTディレクトリ上で以下のコマンドを実行します。

$ bundle exec rake unicorn:start

で、httpdの起動は

$ sudo service httpd start

です。

3
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
3
5