はじめに

CentOS7 + Rails5 + Nginx + puma + PostgreSQLで本番環境を構築したときの作業履歴とメモ。サーバーはさくらのクラウドです。

初期設定

Rails本番環境とは直接関係ない項目もありますが下準備&最低限必要な設定として行いました。

一般ユーザーの作成&sudo&ssh接続設定(公開鍵認証)

【さくらのVPS】サーバの初期設定ガイド

を参考に設定しました。

yum-cronによるパッケージの自動更新

インストール

# yum -y install yum-cron

設定

# vi /etc/yum/yum-cron.conf

自動更新を有効に設定

apply_updates = yes

サービス起動&自動起動設定

# systemctl start yum-cron
# systemctl enable yum-cron

Firewall設定

httpのポートを開けます。また、作業途中の確認用にポート3000も開けます。

# vi /etc/firewalld/zones/public.xml
<zone>
  …省略
  <service name="http"/>
  <port protocol="tcp" port="3000"/>
</zone>

ポート3000は確認が済んだら削除して閉じます。

設定変更したらサービスを再起動します。

# systemctl restart firewalld

PostgreSQL

インストール

# yum -y install postgresql-server postgresql-devel

初期化処理

# postgresql-setup initdb

サービス起動&自動起動設定

# systemctl start postgresql.service
# systemctl enable postgresql.service

パスワード認証に変更

# vi /var/lib/pgsql/data/pg_hba.conf
local   all             all                                     md5
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5

に変更します。

postgresユーザのDB接続パスワード設定

# su - postgres
$ psql -U postgres
postgres=# ALTER USER postgres encrypted password 'パスワード';
postgres=# \q
$ exit

サービス再起動

# systemctl restart postgresql.service

ユーザー作成

# su - postgres
$ createuser -P ユーザー名
パスワード入力

DB作成

作成したユーザーをオーナーとしたDBを作成します。

$ psql -U postgres
postgres=# create database DB名 owner ユーザー名;

rbenv

必要パッケージのインストール

# yum install -y git gcc gcc-c++ openssl-devel readline-devel

インストール

初期設定で作成した一般ユーザーのホームディレクトリで行います。

$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile 
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

rubyインストール

$ rbenv install 2.4.1
$ rbenv global 2.4.1
$ rbenv rehash

bundlerインストール

$ gem install bundler

Railsアプリのデプロイ

Railsアプリのgitリポジトリがある前提です。

初期設定で作成した一般ユーザーのホームディレクトリで行います。

git clone

$ git clone リポジトリURL
$ cd リポジトリ名

パッケージインストール

$ bundle install --without development test

.envファイル作成

$ vi .env

DB接続情報やその他アプリに必要な情報を設定します。

RAILS_DATABASE_USERNAME="ユーザー名"
RAILS_DATABASE_PASSWORD="パスワード"

DB名やホスト、ポートはconfig/database.yml にデフォルト値として設定しています。

production:
  adapter: postgresql
  encoding: unicode
  database: <%= ENV['RAILS_DATABASE'] || 'DB名' %>
  username: <%= ENV['RAILS_DATABASE_USERNAME'] %>
  password: <%= ENV['RAILS_DATABASE_PASSWORD'] %>
  host: <%= ENV['RAILS_DATABASE_HOST'] || 'localhost' %>
  port: <%= ENV['RAILS_DATABASE_PORT'] || '5432' %>

マイグレーション&アセットプリコンパイル

$ RAILS_ENV=production bundle exec rails db:migrate
$ RAILS_ENV=production bundle exec rails assets:precompile

Railsサーバー起動(手動)

$ SECRET_KEY_BASE=$(rake secret) RAILS_SERVE_STATIC_FILES=true RAILS_ENV=production puma -w 2

ブラウザからサーバー名:3000 に接続できることを確認します。確認できたらCtrl + cでサーバーを停止します。また、Firewall設定でポート3000を閉じます。

途中で

Bundler::GemRequireError: There was an error while trying to load the gem 'uglifier'.

のエラーが出たのでGemfileを編集してtherubyracer を使用するように変更したら解消されました。

gem 'therubyracer', platforms: :ruby

Node.jsがインストールされていない環境で発生するようです。

自動起動設定

# vi /etc/systemd/system/puma.service
[Unit]
Description=Puma HTTP Server
After=network.target

[Service]
Type=simple
User=webstaff
WorkingDirectory=/home/ユーザー名/リポジトリ名
Environment="RAILS_ENV=production"
Environment="RAILS_SERVE_STATIC_FILES=true"
Environment="PORT=3000"
ExecStart=/home/ユーザー名/.rbenv/shims/bundle exec puma -C config/puma.rb
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target

.envにSECRET_KEY_BASE を追加します。

$ vi /home/ユーザー名/リポジトリ名/.env

値はプロジェクトルートディレクトリで以下のコマンドの実行結果を使います。

$ rake secret

最後にサービス起動と自動起動設定を行います。

# cd /etc/systemd/system
# systemctl start puma.service
# systemctl enable puma.service

Nginx

インストール

# vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1
# yum install -y nginx

サービス起動&自動起動設定

# systemctl start nginx
# systemctl enable nginx

ブラウザからサーバー名にアクセスできることを確認します。

所有者変更

Railsアプリのファイルは初期設定で作成した一般ユーザーのホームディレクトリ配下にありますので、nginxがアクセスできるように作成した一般ユーザーで実行されるようにします。

# vi /etc/nginx/nginx.conf
user ユーザー名;

に変更します。また、ログファイルを格納するディレクトリの所有者を変更します。

# chown ユーザー名 /var/log/nginx

logrotateの設定を変更します。

# vi /etc/logrotate.d/nginx
create 640 ユーザー名 adm

リバースプロキシ設定

# vi /etc/nginx/conf.d/サーバー名など任意の名前.conf
server {
    listen 80;
    server_name サーバー名;
    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_redirect off;
    proxy_max_temp_file_size 0;
    location / {
        proxy_pass http://localhost:3000;
    }
}

最後にサービスを再起動します。

# systemctl restart nginx