capistrano
unicorn
さくらVPS
Rails5
debian9

さくらサーバで環境構築ゼロから。Railsアプリをデプロイするまで(初心者)

準備

http://vps.sakura.ad.jp/
上にアクセスし、VPSに申し込みを済ませる。
今回メモリは2GB。ストレージの種類 SSD(50GB)。サーバー台数1台。
支払い情報を入力して、申し込み完了!

1、カスタムOSのインストール

参考サイト

・OSをdebianに。(慣れているため)

https://secure.sakura.ad.jp/vps/#/servers
さくらのVPSサーバ一覧から
各種設定

OSインストール

カスタムOSインストール

debian 9を選択しインストール開始(https://www.debian.org/releases/index.ja.html debianバージョン情報)

・VNCコンソールを開き、インストール作業を開始。

Installを選択し、日本語を選択。
ホスト名、ドメイン名、rootパスワード、ユーザーアカウントを入力。

ディスクパーティショニング ”ガイドーディスク全体を使う”→”全ての。。(初心者。。)”を選択→”パーティショニングの終了とディスクへの変更の書き込み”を選択

完了したらxで閉じ、さくらのコンソールの緑の起動ボタンを押してサーバーを起動。

2、ターミナルでsshログインし、鍵認証でログインする方法

参考サイト
ssh鍵認証参考サイト
※windowsの場合はSSHクライアントソフトをインストールする必要がある。

・ターミナルを開き以下のコマンドを入力

ssh 上で設定したuser名@IPアドレス

yesと上で設定したパスワードを入力し、sshログイン完了。

・sshログイン先で以下のコマンドを実行

※手元で自分の公開鍵をコピーしておく。ない人は作成。

$ mkdir .ssh
$ chmod 700 .ssh
$ vi .ssh/authorized_keys
自分の公開鍵をcopy&paste
$ chmod 600 .ssh/authorized_keys

sshログインの設定が完了したので、一旦ログアウトし、もう一度ログインしてみて、パスワード入力も求められずにログインできたらOK。

・sudoをインストール

sshログイン先で

$ su -
# apt-get install sudo
# usermod -G sudo deployer
# su [ユーザー名]

・パスワード認証によるsshアクセスを禁止する方法

参考サイト

$ sudo su
# vi /etc/ssh/sshd_config
PasswordAuthentication no
# service sshd restart

・不要なポート番号を閉じる

こちらを参考に進める。

上記の通り実行したら
/etc/iptables/rules.v4の一行を下記のように変更。

/etc/iptables/rules.v4
-A INPUT -p tcp -m state --state NEW --dport 1234 -j ACCEPT
↓
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

3、必要なものを諸々インストール

・何も考えずに下記のコマンドをsshログイン先で実行。(詳細はいずれわかってくる。はず。)

$ sudo apt-get update
$ sudo apt-get install vim git gcc g++ make nginx mysql-server default-libmysqlclient-dev nodejs libssl-dev libreadline-dev zlib1g-dev letsencrypt
$ sudo apt-get install libmagickwand-dev imagemagick

・nginxのステータスを確認

$ sudo service nginx status
Active: active (running) since Sun 2017-08-27 16:18:48 JST; 35s ago

activeになっていればOK。
IPアドレスにアクセスしてみると、Welcome to nginx!の文字が。

4、rubyをrbenvでインストール

・rbenvをインストール

$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ cd ~/.rbenv && src/configure && make -C src
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
一度ログインし直す。
$ ~/.rbenv/bin/rbenv init

・rubyをインストール

$ rbenv install -l
インストールできるバージョンの一覧が表示される
$ rbenv install 2.4.1
$ rbenv global 2.4.1
$ rbenv exec gem install bundler

Capistranoの導入

・手元での設定

Gemfile

Gemfile
group :development do
  gem 'capistrano', '~> 3.9'
  gem 'capistrano-rails'
  gem 'capistrano-rbenv'
  gem 'capistrano-bundler'
  gem 'capistrano3-unicorn' # unicornを使っている場合のみ
end

gem 'unicorn'
$ bundle install
$ bundle exec cap install

Capfile

Capfile
require 'capistrano/setup'
require 'capistrano/deploy'

require 'capistrano/rails'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano3/unicorn'
# require 'whenever/capistrano'

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

config/deploy.rb

config/deploy.rb
# require 'whenever/capistrano'

lock "3.9.0"

set :application, "my_app_name" #自分のapp_nameに変更
set :repo_url, "git@example.com:me/my_repo.git" #自分のリポジトリURLに変更
set :deploy_to, '/var/www/my_app_name' #自分のapp_nameに変更
set :keep_releases, 3

set :rbenv_type, :user # or :system, depends on your rbenv setup
set :rbenv_ruby, '2.4.1'

set :rbenv_map_bins, %w{rake gem bundle ruby rails}
set :rbenv_roles, :all # default value

set :linked_dirs, %w{log tmp/backup tmp/pids tmp/cache tmp/sockets vendor/bundle}
set :linked_files, %w{config/secrets.yml}

set :bundle_jobs, 4

namespace :deploy do
  task :restart do
    on roles(:web, :app, :db) do |host|
      execute "source /etc/environment"
    end
    invoke 'unicorn:restart'
  end
  after :finishing, 'deploy:cleanup'
end

config/deploy/production.rb

config/deploy/production.rb
set :branch, 'master'

role :app, %w{user_name@IPアドレス}
role :web, %w{user_name@IPアドレス}
role :db,  %w{user_name@IPアドレス}

server 'IPアドレス', user: 'user_name', roles: %w{web app db}

#set :ssh_options, {
#   keys: [File.expand_path('~/.ssh/pays/id_rsa')],
#   forward_agent: true,
#   auth_methods: %w(publickey)
#}

config/unicorn/production.rbを新規作成

config/unicorn/production.rb
rails_root = "/var/www/my_app_name/current" #自分app_nameに変更
shared_path = "/var/www/my_app_name/shared" #自分app_nameに変更

worker_processes 4
working_directory rails_root

#listen "#{rails_root}/tmp/unicorn.sock"
#pid "#{rails_root}/tmp/unicorn.pid"
listen File.expand_path('tmp/sockets/unicorn.sock', shared_path)
pid File.expand_path('tmp/pids/unicorn.pid', shared_path)

stderr_path "#{rails_root}/log/unicorn_error.log"
stdout_path "#{rails_root}/log/unicorn.log"

preload_app true

before_fork do |server, worker|
 ENV['BUNDLE_GEMFILE'] = File.expand_path('Gemfile', rails_root)
 old_pid = "#{server.config[:pid]}.oldbin"
 if File.exists?(old_pid) && server.pid != old_pid
   begin
     sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
     Process.kill(sig, File.read(old_pid).to_i)
   rescue Errno::ENOENT, Errno::ESRCH
     # someone else did our job for us
   end
 end
end

after_fork do |server, worker|
 defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

database.yml

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: 5
  username: root
  password:
  socket: <%= ["/run/mysqld/mysqld5.6.sock",
               "/tmp/mysqld.sock",
               "/var/run/mysqld/mysqld.sock",
               "/var/lib/mysql/mysql.sock",
               "/opt/local/var/run/mysql5/mysqld.sock"].detect {|s| File.exist?(s) } %>

production:
  adapter: mysql2
  encoding: utf8mb4
  pool: 5
  database: my_app_name_production
  username: <%= ENV["DB_USER"] %>
  password: <%= ENV["DB_PASSWORD"] %>

config/initializers/ar_innodb_row_format.rbの作成

以下のファイルを作成。参考サイト

config/initializers/ar_innodb_row_format.rb
ActiveSupport.on_load :active_record do
  module ActiveRecord::ConnectionAdapters
    module CreateTableWithInnodbRowFormat
      def create_table(table_name, options = {})
        table_options = options.merge(options: 'ENGINE=InnoDB ROW_FORMAT=DYNAMIC')
        super(table_name, table_options) do |td|
          yield td if block_given?
        end
      end
    end

    class AbstractMysqlAdapter
      prepend CreateTableWithInnodbRowFormat
    end
  end
end

上記作成後、migrate。

$ bundle exec rake db:migrate

deployする

$ bundle exec cap production deploy

ここで色々エラーを起こすと思いますが、エラー文に従って修正していけば完了。(投げやり

以下にエラーが出て追加で行ったことを記しておきます。
sshログイン後

$ chown -R deployer:deployer /var/www/
$ vim /var/www/my_app_name/shared/config/secrets.yml
手元のsecrets.ymlをcopy&paste

こちらを参考にmysqlにログインできるようにしておく。

$ mysql -u root
mysql> CREATE DATABASE my_app_name_production;

MariaDBに以下の設定を記載

$vi /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld] の中に以下を記載

innodb_file_per_table = 1
innodb_file_format = Barracuda
innodb_large_prefix = 1
innodb_default_row_format = DYNAMIC # >= 5.7.9