多数のrvm + Rails + Nginx + UnicornまたはRailsを正しくデプロイする

このメモの目的は、現在最も人気のあるバンドルであるRailsアプリケーション用のサーバーの構成を説明するために詳しく説明しました:rvm + Rails + Nginx + Unicorn。 記事の執筆は、このバンドルに関する完全なステップバイステップのドキュメントの不足によって促されました。これは、この分野の精力的な専門家だけでなく理解できるものです。 次に、複数のRailsアプリケーションを提供するためにサーバーを編成するイデオロギー的に正しいプロセスをステップごとに詳細に説明します(例として1つを使用)-複数のアプリケーションが実験マシンで動作しないという絶対的な自信がある場合-設定は大幅に短くシンプルになりました。 高負荷下のアプリケーションに関する微妙な点については記事に記載されていないことを警告します。 目標は異なっていました-アプリケーションを連携して動作させ、他のアプリケーションとの競合の数を最小限に抑えること。



SSHキー


ヘッダーにリストされているツールを使用する前に、すべてを整理するサーバーを準備する必要があります。 サーバーに新しいUbuntu 10.04 LTSをインストールし(+最初のユーザーのプロセスで開始)、そこでOpenSSHデーモンを起動したとします。 それだけです! これからは、腕、脚、その他の四肢をサーバーに触れないでください-リモートでのみ作業します。

ssh-copy-id vasya@rails-production.example.com
      
      



ここで、vasyaはサーバー上のユーザーの名前であり、そのユーザーに代わってデプロイが実行されます。rails-production.example.comは、先ほど上げたサーバーのアドレスまたは名前です。 入力後、マシン上の既知のホストのリストにホストを追加することに同意する必要があります-大丈夫です-それで構いません。 そしてパスワードを入力します。 これは、バジルのパスワードを入力する最後の時間になります。 これで、sshキーでサーバーにアクセスできるようになり、何も入力する必要がなくなりました。



これらは言及する価値のない基本事項のように思えますが、sshキーを使用してマシンにアクセスするための別の視点を持つ人々の割合は常に存在します。 彼らのために、私はブラシの関節の関節炎のための軟膏を助言することができます、残りのために私はsshキーが祝福であると信じることを単に提案します。



データベース


ここでは、最も一般的な2つのDBMSに必要なパッケージのインストールに関するヒントのみを紹介します。

 sudo apt-get install mysql-server mysql-client libmysqld-dev # MySQL sudo apt-get install postgresql postgresql-client postgresql-server-dev #Postgresql
      
      



サーバー上でDBMSをチューニングすることは別の記事のトピックなので、これを自分で処理できると仮定します。 したがって-タダアム! DBMSが稼働しています。



Rvm


RvmはRubyのバージョン管理システムツールであり、gemとは別の「環境」を作成できますが、この場合は重要ではありません。 バンドラーとRvmのgemsetsの概念を検討すると、特定のアプリケーションの環境を分離するという同じ目的で設計されていると感じるかもしれません。 Bundlerはgemの依存関係を解決する優れた方法であり、Rails 3はデフォルトで動作します。 そして一般的に、これについて話しているので、Rails 2.3.xにbundlerを使用することをお勧めします 。これを行う方法については、 ここで説明します



Rvmは、異なるバージョンのRubyを簡単に切り替えるためにのみ必要です。そのようなニーズは、異なるバージョンのRuby on Railsで記述されたアプリケーションが同時にスピンするサーバーで発生する可能性が高いでしょう。 Rvmにも敵がいます。 いいえ、実際、この鉄片で複数のバージョンのルビーが動作しないことを完全に確信している場合、ルビーシステムインタープリターとして何らかの種類のリーをインストールし、 静かに地獄燃やして人生を楽しむことがより正しいでしょう。 しかし、現実は厳しいので、私はrvmを使用することをお勧めします-これはすべてのものを整然と保ちます。



すでにドキュメントを読んでいる場合は、Rvmをルート(いわゆるシステム全体のインストール)からインストールする方法と、単純なユーザー用の通常の方法の2つがあることに気づいたでしょう。 だから、もう一度私はあなたの信仰をテストしたい-ルートからインストールしないでください。 無駄ではありませんが、展開を担当するユーザーを作成しました。 したがって、バジルの下のサーバーに移動して、次の一連のコマンドを実行します。



 sudo apt-get install git-core curl #  ,    Rvm. curl -L https://get.rvm.io | bash -s stable --ruby type rvm | head -1
      
      



最後のコマンドは、「rvm is a function」またはロシア語の類似語を生成します。 これが起こらない場合- ここから今までの研究開始する価値があります-「それが機能するまで」。



ルビー


rubyのバージョンの選択は、アプリケーションで使用されているレールのバージョンによって異なります。したがって、2.3.xではRuby Enterprise Editionを使用することをお勧めします。3.xでは1.9.3を使用することをお勧めします。 私の場合、これはそれぞれ2.3.xとreeのアプリケーションです。 そして、システムからruby 1.9.3をインストールするために特別なものが必要でない場合、reeをインストールするためにいくつかのシステムパッケージが必要です。

 sudo apt-get install build-essential bison openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev rvm install ree-1.8.7-2011.03 #  ree rvm ree # ,   Ruby .      -     : rvm ree@myapp --create.   Bundler    . gem install bundler #  gem,    . sudo mkdir -p /srv/myapp #  ,      . sudo chown -R vasya:vasya /srv/myapp #      (   ,  -R  ).
      
      







Nginx


Unicornを使用するので、Nginxなしではできません-Unicornにはこのような機能があります-遅いクライアントでは機能しません。 確かに、それに相当するものがあります。これはRainbowsかもしれませんが、Nginx自体は非常に便利で、使いやすくて便利です。 この素晴らしいサーバーの作成者であるIgor SysoevのWebサイトでインストール手順を見つけることができます。 nginxとnginx.confを実行する単純なinitスクリプトを提供します。

 #! /bin/sh EXEC_PATH="/usr/local/nginx/sbin/nginx" case "$1" in start) echo "Starting NginX" start-stop-daemon --start --exec $EXEC_PATH ;; stop) echo "Stopping NginX" start-stop-daemon --stop --exec $EXEC_PATH ;; restart) echo "Stopping NginX" start-stop-daemon --stop --exec $EXEC_PATH sleep 1 echo "Starting NginX" start-stop-daemon --start --exec $EXEC_PATH ;; *) echo "Usage: {start|stop|restart}" exit 1 ;; esac exit 0
      
      





 worker_processes 1; #       . user vasya vasya; #      worker -   ,    . pid /tmp/nginx.pid; #       - Nginx. error_log /tmp/nginx.error.log; events { worker_connections 1024; #        . accept_mutex off; #         - . } http { #     -       - -  : include mime.types; default_type application/octet-stream; access_log /tmp/nginx.access.log combined; sendfile on; tcp_nopush on; tcp_nodelay off; gzip on; #    .    upstream .        ,     . upstream myapp_server { server unix:/srv/myapp/shared/unicorn.sock fail_timeout=0; #        config/unicorn.rb    . } server { listen 80 default deferred; #  ,       ip   ,      -  myapp.mydomain.ru:80 client_max_body_size 1G; #     (   -       ). server_name myapp.mydomain.ru; #   keepalive_timeout 5; root /srv/myapp/current/public; #        public Rails .  current       Capistrano try_files $uri/index.html $uri.html $uri @myapp; #     - ,    location    location @myapp { proxy_pass http://myapp_server; #   http://       upstream . proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; } error_page 500 502 503 504 /500.html; location = /500.html { root /srv/myapp/current/public; } } }
      
      





Nginxが複数のアプリケーションを同時に提供する場合、 server { ... }



ブロックを/usr/local/nginx/conf/vhosts



内の個別のファイルに移動し、 /usr/local/nginx/conf/vhosts



include /usr/local/nginx/conf/vhosts/*



を書き込む必要があることをすぐに警告する価値がありserver { ... }



include /usr/local/nginx/conf/vhosts/*



-例では、わかりやすくするためにこれを行っていません。



ユニコーン


Unicornはシステム全体にインストールできますが、これは実行しないでください。Gemfileに対応するgemを含める方がはるかに正確です。
 gem 'unicorn'
      
      



そして、 bundle exec



コマンドでUnicornを実行します。 ちなみに、この推奨事項はUnicornだけでなく、gemに付属する実行可能ファイルにも適用されます。 特定のアプリケーションにUnicornをインストールすると、1台のマシンでできるだけ多くのアプリケーションを簡単に取得できます。

次に、いわゆるゼロダウンタイムデプロイを提供するサーバー構成の例を示します。 config / unicorn.rb:

 deploy_to = "/srv/myapp" rails_root = "#{deploy_to}/current" pid_file = "#{deploy_to}/shared/pids/unicorn.pid" socket_file= "#{deploy_to}/shared/unicorn.sock" log_file = "#{rails_root}/log/unicorn.log" err_log = "#{rails_root}/log/unicorn_error.log" old_pid = pid_file + '.oldbin' timeout 30 worker_processes 4 #      ,       listen socket_file, :backlog => 1024 pid pid_file stderr_path err_log stdout_path log_file preload_app true #    ,  ,    . GC.copy_on_write_friendly = true if GC.respond_to?(:copy_on_write_friendly=) #   ,    ,     . before_exec do |server| ENV["BUNDLE_GEMFILE"] = "#{rails_root}/Gemfile" end before_fork do |server, worker| #  ,     ,    . defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! #   ,   0 downtime deploy. if File.exists?(old_pid) && server.pid != old_pid begin Process.kill("QUIT", 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
      
      







カピストラーノ


まあ、私たちは基本的なことができるすべてすでに設定しているので、あなたはカピストラーノに対処する必要があります。 まず、capistrano gemをGemfileの開発グループに配置し、そこにrvmとの統合のためにrvm-capistranoを配置します(バージョンrvm> = 1.1.0の場合)。

 group :development do gem "capistrano" gem "rvm-capistrano" end
      
      



gemをインストールした後、次のコマンドを実行します。
 bundle exec capify .
      
      



そして、ほとんど空のconfig / deploy.rbファイルを取得します。 ニーズに合ったファイルの例を示します。
 require 'rvm/capistrano' #   rvm require 'bundler/capistrano' #   bundler.    bundler      ,       . set :application, "myapp" set :rails_env, "production" set :domain, "vasya@rails-production.example.com" #      ssh.             ,    . set :deploy_to, "/srv/#{application}" set :use_sudo, false set :unicorn_conf, "#{deploy_to}/current/config/unicorn.rb" set :unicorn_pid, "#{deploy_to}/shared/pids/unicorn.pid" set :rvm_ruby_string, 'ree' #    ,  Ruby    . set :scm, :git #  git. , ,  -  - svn, ,         git -  git. set :repository, "git@github.com:myprojects/myapp.git" #    . ,         ,   ,     rsa        deployment keys   . set :branch, "master" #        . set :deploy_via, :remote_cache #   ,              .       . role :web, domain role :app, domain role :db, domain, :primary => true before 'deploy:setup', 'rvm:install_rvm', 'rvm:install_ruby' #  rvm  capistrano  ,    cap deploy:setup      rvm_ruby_string . after 'deploy:update_code', :roles => :app do #           - database.yml.       /srv/myapp/shared/config    .           . run "rm -f #{current_release}/config/database.yml" run "ln -s #{deploy_to}/shared/config/database.yml #{current_release}/config/database.yml" end #      unicorn.       -  . #    Rails 3    bundle exec unicorn_rails  bundle exec unicorn namespace :deploy do task :restart do run "if [ -f #{unicorn_pid} ] && [ -e /proc/$(cat #{unicorn_pid}) ]; then kill -USR2 `cat #{unicorn_pid}`; else cd #{deploy_to}/current && bundle exec unicorn_rails -c #{unicorn_conf} -E #{rails_env} -D; fi" end task :start do run "bundle exec unicorn_rails -c #{unicorn_conf} -E #{rails_env} -D" end task :stop do run "if [ -f #{unicorn_pid} ] && [ -e /proc/$(cat #{unicorn_pid}) ]; then kill -QUIT `cat #{unicorn_pid}`; fi" end end
      
      







PS提示された資料または建設的なコメントを改善するための提案を誰かが思いついた場合、私は読んで修正することを嬉しく思います。



All Articles