Capistrano、Nginx、Pumaを使用してUbuntu14.04にRailsアプリをデプロイする
序章
Railsは、Rubyで記述されたオープンソースのWebアプリケーションフレームワークです。 これは、設定より規約の哲学に従い、物事を行うための「最良の」方法があると仮定しています。 これにより、無限の構成ファイルを経由することなく、より多くのことを達成しながら、より少ないコードを書くことができます。
Nginxは、高性能HTTPサーバー、リバースプロキシ、および同時実行性、安定性、スケーラビリティ、および低メモリ消費に重点を置いていることで知られるロードバランサーです。 Nginxと同様に、Pumaは、メモリフットプリントが非常に小さいが、RubyWebアプリケーション用に構築されたもう1つの非常に高速で同時実行のWebサーバーです。
Capistranoは、主にRubyWebアプリに焦点を当てたリモートサーバー自動化ツールです。 これは、SSHを介して任意のワークフローをスクリプト化し、アセットの事前コンパイルやRailsサーバーの再起動などの一般的なタスクを自動化することにより、任意の数のリモートマシンにWebアプリを確実にデプロイするために使用されます。
このチュートリアルでは、RubyとNginxをDigitalOcean Ubuntuドロップレットにインストールし、WebアプリでPumaとCapistranoを構成します。 Nginxは、クライアントリクエストをキャプチャし、Railsを実行しているPumaWebサーバーに渡すために使用されます。 Capistranoを使用して一般的なデプロイタスクを自動化するため、Railsアプリの新しいバージョンをサーバーにデプロイする必要があるたびに、いくつかの簡単なコマンドでそれを実行できます。
前提条件
このチュートリアルに従うには、次のものが必要です。
- Ubuntu14.04×64ドロップレット
- sudo権限を持つ
deploy
という名前の非rootユーザー( Ubuntu 14.04 を使用した初期サーバーセットアップでは、これをセットアップする方法について説明しています)。 - デプロイの準備ができているリモートgitリポジトリでホストされているWorkingRailsアプリ
オプションで、セキュリティを強化するために、SSH経由のrootログインを無効にし、 Ubuntu14.04を使用したサーバーの初期設定の説明に従ってSSHポート番号を変更できます。
警告: rootログインを無効にした後、deploy
ユーザーとしてDropletにSSHで接続し、を閉じる前にこのユーザーにsudo
を使用できることを確認してください。これらの変更を行うために開いたrootSSHセッション。
このチュートリアルのすべてのコマンドは、deploy
ユーザーとして実行する必要があります。 コマンドにrootアクセスが必要な場合は、その前にsudo
が付きます。
ステップ1—Nginxをインストールする
VPSが安全になったら、パッケージのインストールを開始できます。 パッケージインデックスファイルを更新します。
- sudo apt-get update
次に、Nginxをインストールします。
- sudo apt-get install curl git-core nginx -y
ステップ2—データベースのインストール
Railsアプリで使用するデータベースをインストールします。 選択できるデータベースはたくさんあるので、このガイドではそれらについては説明しません。 あなたはここで主要なもののための指示を見ることができます:
また、必ずチェックしてください:
ステップ3—RVMとRubyをインストールする
Rubyを直接インストールすることはありません。 代わりに、Rubyバージョンマネージャーを使用します。 選択できるものはたくさんありますが(rbenv、chrubyなど)、このチュートリアルではRVMを使用します。 RVMを使用すると、同じシステムに複数のルビーを簡単にインストールして管理し、アプリに応じて適切なルビーを使用できます。 これにより、新しいRubyを使用するためにRailsアプリをアップグレードする必要がある場合に、作業がはるかに簡単になります。
RVMをインストールする前に、RVMGPGキーをインポートする必要があります。
- gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
次に、RVMをインストールしてRubiesを管理します。
- curl -sSL https://get.rvm.io | bash -s stable
このコマンドは、curl
を使用して、https://get.rvm.io
からRVMインストールスクリプトをダウンロードします。 -sSL
オプションは、次の3つのフラグで構成されています。
-s
は、ファイルを「サイレントモード」でダウンロードするようにcurlに指示します-S
は、失敗した場合にエラーメッセージを表示するようにcurlに指示します-L
は、インストールスクリプトの取得中にすべてのHTTPリダイレクトに従うようにcurlに指示します
ダウンロードされると、スクリプトはパイプからbash
になります。 -s
オプションは、stable
を引数としてRVMインストールスクリプトに渡し、RVMの安定リリースをダウンロードしてインストールします。
注: 2番目のコマンドが「GPG署名の検証に失敗しました」というメッセージで失敗した場合、つまりGPGキーが変更された場合は、エラー出力からコマンドをコピーして実行し、署名をダウンロードします。 次に、RVMインストールのcurlコマンドを実行します。
RVMスクリプトを(関数として)ロードして、使用を開始できるようにする必要があります。 次に、requirements
コマンドを実行して、RVMとRubyが正しく機能するために必要な依存関係とファイルを自動的にインストールする必要があります。
- source ~/.rvm/scripts/rvm
- rvm requirements
これで、選択したRubyをインストールできます。 最新のRuby 2.2.1
(執筆時点)をデフォルトのRubyとしてインストールします。
- rvm install 2.2.1
- rvm use 2.2.1 --default
ステップ4—RailsとBundlerをインストールする
Rubyをセットアップしたら、Rubygemsのインストールを開始できます。 まず、Railsアプリケーションを実行できるようにするRails gemをインストールします。次に、アプリのGemfile
を読み取り、必要なすべてのgemを自動的にインストールできるbundler
をインストールします。
RailsとBundlerをインストールするには:
- gem install rails -V --no-ri --no-rdoc
- gem install bundler -V --no-ri --no-rdoc
3つのフラグが使用されました:
-V
(詳細出力):Gemのインストールに関する詳細情報を出力します--no-ri
-(Riドキュメントをスキップ):Riドキュメントをインストールしないため、スペースが節約され、インストールが高速になります--no-rdoc
-(RDocsをスキップ):RDocsをインストールしないため、スペースが節約され、インストールが高速化されます
注: -v
フラグを使用して、要件に応じて特定のバージョンのRailsをインストールすることもできます。
- gem install rails -v '4.2.0' -V --no-ri --no-rdoc
ステップ5—SSHキーを設定する
スムーズな展開を設定したいので、認証にSSHキーを使用します。 まず、RailsアプリのコードベースがホストされているGitHub、Bitbucket、またはその他のGitRemoteと握手します。
- ssh -T [email protected]
- ssh -T [email protected]
Permission denied (publickey)
メッセージが表示されても心配しないでください。 次に、サーバーのSSHキー(公開鍵と秘密鍵のペア)を生成します。
- ssh-keygen -t rsa
新しく作成した公開鍵(~/.ssh/id_rsa.pub
)をリポジトリの展開鍵に追加します。
すべての手順が正しく完了すると、パスワードを入力せずにgitリポジトリをclone
(HTTPではなくSSHプロトコル経由で)実行できるようになります。
- git clone [email protected]:username/appname.git
テスト用のサンプルアプリが必要な場合は、このチュートリアル用に特別に作成された次のテストアプリをフォークできます。GitHub上のサンプルRailsアプリ
git clone
コマンドは、アプリと同じ名前のディレクトリを作成します。 たとえば、testapp_rails
という名前のディレクトリが作成されます。
クローンを作成しているのは、デプロイメントキーが機能しているかどうかを確認するためだけです。新しい変更をプッシュするたびに、リポジトリをクローンしたりプルしたりする必要はありません。 Capistranoにすべてを任せます。 必要に応じて、この複製されたディレクトリを削除できるようになりました。
ローカルマシンでターミナルを開きます。 ローカルコンピューター用のSSHキーがない場合は、SSHキーも作成します。 ローカルターミナルセッション:
- ssh-keygen -t rsa
ドロップレットの承認済みキーファイルにローカルSSHキーを追加します(ポート番号をカスタマイズしたポート番号に置き換えることを忘れないでください)。
- cat ~/.ssh/id_rsa.pub | ssh -p your_port_num deploy@your_server_ip 'cat >> ~/.ssh/authorized_keys'
ステップ6—Railsアプリにデプロイメント構成を追加する
ローカルマシンで、RailsアプリケーションでNginxとCapistranoの構成ファイルを作成します。 RailsアプリのGemfile
に次の行を追加することから始めます。
group :development do
gem 'capistrano', require: false
gem 'capistrano-rvm', require: false
gem 'capistrano-rails', require: false
gem 'capistrano-bundler', require: false
gem 'capistrano3-puma', require: false
end
gem 'puma'
bundler
を使用して、Gemfile
で指定したgemをインストールします。 次のコマンドを入力して、Railsアプリをバンドルします。
- bundle
バンドル後、次のコマンドを実行してCapistranoを構成します。
- cap install
これにより、次のものが作成されます。
- Railsアプリのルートディレクトリにある
Capfile
config
ディレクトリのdeploy.rb
ファイルconfig
ディレクトリ内のdeploy
ディレクトリ
Capfile
の内容を次のように置き換えます。
# Load DSL and Setup Up Stages
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rails'
require 'capistrano/bundler'
require 'capistrano/rvm'
require 'capistrano/puma'
# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
このCapfile
は、いくつかの事前定義されたタスクをCapistrano構成ファイルにロードして、展開を手間をかけずに自動的に行います。
- 正しいRubyを選択する
- アセットのプリコンパイル
- Gitリポジトリを正しい場所に複製する
- Gemfileが変更されたときに新しい依存関係をインストールする
config/deploy.rb
の内容を次のように置き換え、アプリとドロップレットパラメーターで赤でマークされたフィールドを更新します。
# Change these
server 'your_server_ip', port: your_port_num, roles: [:web, :app, :db], primary: true
set :repo_url, '[email protected]:username/appname.git'
set :application, 'appname'
set :user, 'deploy'
set :puma_threads, [4, 16]
set :puma_workers, 0
# Don't change these unless you know what you're doing
set :pty, true
set :use_sudo, false
set :stage, :production
set :deploy_via, :remote_cache
set :deploy_to, "/home/#{fetch(:user)}/apps/#{fetch(:application)}"
set :puma_bind, "unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
set :puma_access_log, "#{release_path}/log/puma.error.log"
set :puma_error_log, "#{release_path}/log/puma.access.log"
set :ssh_options, { forward_agent: true, user: fetch(:user), keys: %w(~/.ssh/id_rsa.pub) }
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, true # Change to false when not using ActiveRecord
## Defaults:
# set :scm, :git
# set :branch, :master
# set :format, :pretty
# set :log_level, :debug
# set :keep_releases, 5
## Linked Files & Directories (Default None):
# set :linked_files, %w{config/database.yml}
# set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
namespace :puma do
desc 'Create Directories for Puma Pids and Socket'
task :make_dirs do
on roles(:app) do
execute "mkdir #{shared_path}/tmp/sockets -p"
execute "mkdir #{shared_path}/tmp/pids -p"
end
end
before :start, :make_dirs
end
namespace :deploy do
desc "Make sure local git is in sync with remote."
task :check_revision do
on roles(:app) do
unless `git rev-parse HEAD` == `git rev-parse origin/master`
puts "WARNING: HEAD is not the same as origin/master"
puts "Run `git push` to sync changes."
exit
end
end
end
desc 'Initial Deploy'
task :initial do
on roles(:app) do
before 'deploy:restart', 'puma:start'
invoke 'deploy'
end
end
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
invoke 'puma:restart'
end
end
before :starting, :check_revision
after :finishing, :compile_assets
after :finishing, :cleanup
after :finishing, :restart
end
# ps aux | grep puma # Get puma pid
# kill -s SIGUSR2 pid # Restart puma
# kill -s SIGTERM pid # Stop puma
このdeploy.rb
ファイルには、すぐに使用できるいくつかの正常なデフォルトが含まれており、アプリのリリースを管理し、デプロイ時にいくつかのタスクを自動的に実行するのに役立ちます。
- Railsアプリのデフォルト環境として
production
を使用します - アプリの複数のリリースを自動的に管理します
- 最適化されたSSHオプションを使用
- gitリモートが最新かどうかを確認します
- アプリのログを管理します
- Pumaワーカーを管理するときに、アプリをメモリにプリロードします
- デプロイメントの終了後にPumaサーバーを起動(または再起動)します
- リリース内の特定の場所にあるPumaサーバーへのソケットを開きます
要件に応じて、すべてのオプションを変更できます。 ここで、Nginxを構成する必要があります。 Railsプロジェクトディレクトリにconfig/nginx.conf
を作成し、それに以下を追加します(ここでも、パラメーターに置き換えます)。
upstream puma {
server unix:///home/deploy/apps/appname/shared/tmp/sockets/appname-puma.sock;
}
server {
listen 80 default_server deferred;
# server_name example.com;
root /home/deploy/apps/appname/current/public;
access_log /home/deploy/apps/appname/current/log/nginx.access.log;
error_log /home/deploy/apps/appname/current/log/nginx.error.log info;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri @puma;
location @puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 10M;
keepalive_timeout 10;
}
前のファイルと同様に、このnginx.conf
には、deploy.rb
ファイルの構成ですぐに機能するデフォルトが含まれています。 これはポート80でトラフィックをリッスンし、リクエストをPumaソケットに渡し、nginxログをアプリの「現在の」リリースに書き込み、すべてのアセットを圧縮して最大有効期限でブラウザーにキャッシュし、パブリックでHTMLページを提供しますフォルダを静的ファイルとして設定し、デフォルトの最大Client Body Size
およびRequest Timeout
値を設定します。
ステップ7—Railsアプリケーションをデプロイする
独自のRailsアプリを使用している場合は、行った変更をコミットし、ローカルマシンからリモートにプッシュします。
- git add -A
- git commit -m "Set up Puma, Nginx & Capistrano"
- git push origin master
注:このシステムからGitHubを初めて使用する場合は、GitHubのユーザー名とメールアドレスを使用して次のコマンドを発行する必要がある場合があります。
- git config --global user.name 'Your Name'
- git config --global user.email [email protected]
ここでも、ローカルマシンから、最初の展開を行います。
- cap production deploy:initial
これにより、RailsアプリがDropletにプッシュされ、アプリに必要なすべてのgemがインストールされ、PumaWebサーバーが起動します。 これには、アプリが使用するGemsの数に応じて、5〜15分かかる場合があります。 このプロセスが発生すると、デバッグメッセージが表示されます。
すべてが順調に進んだら、PumaWebサーバーをNginxリバースプロキシに接続する準備が整いました。
ドロップレットで、nginx.conf
をsites-enabled
ディレクトリにシンボリックリンクします。
- sudo rm /etc/nginx/sites-enabled/default
- sudo ln -nfs "/home/deploy/apps/appname/current/config/nginx.conf" "/etc/nginx/sites-enabled/appname"
Nginxサービスを再起動します。
- sudo service nginx restart
これで、WebブラウザーでサーバーIPを指定し、Railsアプリの動作を確認できるようになります。
通常の展開
アプリに変更を加えてサーバーに新しいリリースをデプロイする場合は、変更をコミットし、通常どおりgitリモートにプッシュして、deploy
コマンドを実行します。
- git add -A
- git commit -m "Deploy Message"
- git push origin master
- cap production deploy
注: config/nginx.conf
ファイルに変更を加えた場合は、アプリをデプロイした後、サーバーでNginxサービスをリロードまたは再起動する必要があります。
- sudo service nginx restart
結論
さて、これで、WebサーバーとしてPumaを使用し、基本設定で構成されたNginxとCapistranoを使用してDropletでRailsアプリを実行することになります。 ここで、Railsアプリケーションを最大限に活用するために構成を最適化するのに役立つ他のドキュメントを確認する必要があります。