ruby on rails 伺服器配置

mj發表於2014-07-21

近期各種伺服器變更, 積累了一些伺服器的配置經驗.

首先, 我們沒有采用chef等來部署我們的伺服器, 因為我們的伺服器的國內阿里雲, chef等伺服器的源在國外ec2, 陪一臺伺服器的時間絕對的災難, 所以只能手動來了.

首先是我們的伺服器需要的環境:
1. ruby 2.1
2. 資料庫
3. nginx
4. redis
5. 監控(程式監控, 伺服器監控)

一步一步來:
選擇系統, 我們一直是ubuntu的忠實使用者, 這裡選擇ubuntu 12.04
登入伺服器, 安裝好基礎環境

sudo apt-get install nodejs redis-server libmysqlclient-dev nginx monit htop

安裝rvm

curl -sSL https://get.rvm.io | bash -s stable
# 根據提示執行一下rvm
sed -i `s!cache.ruby-lang.org/pub/ruby!ruby.taobao.org/mirrors/ruby!` $rvm_path/config/db
rvm install ruby

配置監控

基礎配置
sudo vim /etc/monit/monitrc 開啟以下配置

set httpd port 2812 and
     use address localhost  # only accept connection from localhost
     allow localhost        # allow localhost to connect to the server and
     allow admin:monit      # require user `admin` with password `monit`
     allow @monit           # allow users of group `monit` to connect (rw)
     allow @users readonly  # allow users of group `users` to connect readonly

sudo vim /etc/monit/conf.d/nginx 新增nginx監控

check process nginx with pidfile /var/run/nginx.pid
    start program = "/etc/init.d/nginx start"
    stop program = "/etc/init.d/nginx stop"

sudo vim /etc/monit/conf.d/redis 新增redis監控

check process redis-server
    with pidfile "/var/run/redis/redis.pid"
    start program = "/etc/init.d/redis-server start"
    stop program = "/etc/init.d/redis-server stop"
    if 2 restarts within 3 cycles then timeout
    if totalmem > 100 Mb then alert
    if children > 255 for 5 cycles then stop
    if cpu usage > 95% for 3 cycles then restart
    if failed host 127.0.0.1 port 6379 then restart
    if 5 restarts within 5 cycles then timeout

新增專案的部署指令碼, 我們的是Capistrano 3

在rails專案的Gemfile新增下面內容, 並執行bundle install

group :development do
  gem `capistrano-rails`
  gem `capistrano-rvm`
  gem `capistrano-sidekiq`, `~> 0.3.3`
  gem `capistrano3-puma`
end

group :production do
  gem `newrelic_rpm`
  gem `puma`
end

在rails的專案目錄裡使用cap install新增部署指令碼, 編輯Capfile如下顯示

# Load DSL and Setup Up Stages
require `capistrano/setup`

# Includes default deployment tasks
require `capistrano/deploy`

require `capistrano/rvm`
require `capistrano/bundler`
require `capistrano/rails/assets`
require `capistrano/rails/migrations`
require `capistrano/sidekiq`
require `capistrano/sidekiq/monit`
require `capistrano/puma`
require `capistrano/puma/monit`

# Loads custom tasks from `lib/capistrano/tasks` if you have any defined.
Dir.glob(`lib/capistrano/tasks/*.rake`).each { |r| import r }

編輯config/deploy.rb

# config valid only for Capistrano 3.1
lock `3.2.1`

set :application, `你的專案名`
set :repo_url, `你的git地址`

set :deploy_to, `部署的目標目錄`

set :scm, :git


# Default value for :linked_files is []
set :linked_files, %w{config/database.yml}

# Default value for linked_dirs is []
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}


set :keep_releases, 5

after `deploy:publishing`, `deploy:restart`

namespace :deploy do



  desc `Restart application`
  task :restart do
    on roles(:web) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          # execute :rake, "up_assets"
        end
      end
    end
  end

  after :restart, :clear_cache do
    on roles(:web), in: :groups, limit: 3, wait: 10 do

    end
  end

  after :finishing, `deploy:cleanup`
  before :finishing, `deploy:restart`

  after `deploy:rollback`, `deploy:restart`
end

編輯config/deploy/production.rb

# Simple Role Syntax

set :rvm_type, :user
set :rvm_ruby_version, `ruby-2.1.2`


role :app, %w{deployer@youdoman.com}
role :web, %w{deployer@youdoman.com}
role :db,  %w{deployer@youdoman.com}

set :branch, "master"

server `youdoman.com`, user: `deployer`, roles: %w{app web}, my_property: :my_value

set :puma_rackup, -> { File.join(current_path, `config.ru`) }
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"    #accept array for multi-bind
set :puma_conf, "#{shared_path}/puma.rb"
set :puma_access_log, "#{shared_path}/log/puma_error.log"
set :puma_error_log, "#{shared_path}/log/puma_access.log"
set :puma_role, :app
set :puma_env, fetch(:rack_env, fetch(:rails_env, `production`))
set :puma_threads, [0, 120]
set :puma_workers, 0
set :puma_worker_timeout, nil
set :puma_init_active_record, false
set :puma_preload_app, true

提交程式碼到程式碼倉庫, 使用cap production deploy部署系統
部署完畢之後使用
cap production puma:monit:config
cap production sidekiq:monit:config
把我們的web server和後臺佇列進行監控, 注意這裡可以有許可權問題, 報錯的時候可以登入到伺服器吧/tmp 目錄裡對應的檔案拷貝到/etc/monit 目錄中.
最後使用sudo monit reload重新載入監控, 使用monit status檢視系統情況.

登入到伺服器新增nginx

sudo vim /etc/nginx/sites-enabled/you_project_name

upstream app {
  server unix:/xxx/xxx/puma.sock; # puma 部署完之後會得到一個sock地址, 修改成類似的格式,新增進來即可
}


server {
  listen 80;
  server_name youserver_name;
  root /xxx/xxx/current/public;

  try_files $uri/index.html $uri @app;

  location @app {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
}

重啟nginx. 到這裡系統基本部署完畢, 至於程式級別的監控我們採用的是newrelic, 如果需要使用, 可以google newrelic 註冊一個免費的帳號, 根據提示新增你的專案中.

相關文章