部署Rails CentOS6.5 ( Nginx+Puma+Mina )

CentOS用户操作

  1. 创建新用户和组

    1. useradd deploy -G admin -p deploy
    • 创建新组admin,新用户deploy,密码deploy,并将deploy用户加入admin组。
    1. 创建部署目标文件夹
      1. mkdir -p /var/www/myapp
      2. chown -R deploy /var/www/myapp
  2. 设置ssh

    • vi /etc/ssh/ssh_config
    • Port 13579可以修改ssh的端口
    • RSAAuthentication yesRSA验证
    • PasswordAuthentication yes密码验证
    • PermitEmptyPasswords no不允许空密码登录
    • AllowUsers deploy只允许指定用户
  3. 开启ssh

    1. service sshd start开启ssh
    2. chkconfig sshd on开机启动
  4. shh公钥免密码登录

    • 如果是mac用户,可以用ssh-copy-id
      1. brew install ssh-copy-id下载ssh-copy-id
      2. ssh-copy-id [email protected]
      3. 用密码登录一次,OK了,就这么简单
    • 传统做法
      1. ssh [email protected]
      2. cd /home/deploy
      3. mkdir ./.ssh
      4. 回到自己的本地Terminal
      5. scp /path/to/.ssh/id_rsa.pub [email protected]/deploy/.ssh/authorized_keys将本地RSA公钥复制到服务器

Ruby开发环境搭建

  1. 安装需要的软件
- `sudo yum install -y git-core openssl bzip2 bzip2-devel gcc ruby-devel zlib-devel libxml2`

- 安装MySQL
  1. mysql`sudo rpm -e --nodeps mysql`删除本地
  2. `sudo yum install -y mysql-server mysql mysql-deve`
  3. `sudo service mysqld start`开启mysql
  4. `sudo service mysqld start`设置开机启动

- 安装Node
  1. `wget http://nodejs.org/dist/v0.12.2/node-v0.12.2.tar.gz`下载
  2. `tar -zvxf node-v0.12.2.tar.gz`解压
  3. `cd node-v0.12.2`
  4. `sudo make & make install`编译

- 安装Nginx
  1. `mkdir /etc/yum.repos.d/nginx.repo` 设置Nginx的镜像配置文件

          [nginx]
          name=nginx repo
          baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
          gpgcheck=0
          enabled=1
      
  2. `sudo yum install nginx`

1. 安装rvm
1. `curl -L https://get.rvm.io | bash -s stable` 下载rvm
2. `sed -i 's!ftp.ruby-lang.org/pub/ruby!ruby.taobao.org/mirrors/ruby!' $rvm_path/config/db` 将rvm的资源地址换到taobao
  1. 安装Ruby
- `rvm 2.1.4`安装ruby-2.1.4
- 改变gem source
  - `gem sources --remove https://rubygems.org/`
  - `gem sources -a http://ruby.taobao.org/`
- 安装bundle
  - `gem install bundle --no-rdoc --no-ri`

配置Puma

  1. 首先要在Gemfile中添加gem 'puma'

  2. Puma中文文档

  3. myapp/config/puam.rb

     #!/usr/bin/env puma
    
     environment ENV['RAILS_ENV'] || 'development'
    
     daemonize true
    
     pidfile "//var/www/myapp/tmp/pids/puma.pid"
     stdout_redirect "//var/www/myapp/log/stdout", "//var/www/myapp/log/stderr"
    
     threads 0, 16
    
     bind "unix:///tmp/deploy.sock"
    
  4. myapp/bin/puma.sh

    • 用于puma的操作
  #! /bin/sh
  PUMA_CONFIG_FILE=/var/www/myapp/config/puma.rb
  PUMA_PID_FILE=/var/www/myapp/tmp/pids/puma.pid
  PUMA_SOCKET=/var/www/myapp/tmp/sockets/puma.sock

  # check if puma process is running
  puma_is_running() {
    if [ -S $PUMA_SOCKET ] ; then
      if [ -e $PUMA_PID_FILE ] ; then
        if cat $PUMA_PID_FILE | xargs pgrep -P > /dev/null ; then
          return 0
        else
          echo "No puma process found"
        fi
      else
        echo "No puma pid file found"
      fi
    else
      echo "No puma socket found"
    fi

    return 1
  }

  case "$1" in
    start)
      echo "Starting puma..."
        rm -f $PUMA_SOCKET
        touch -f $PUMA_SOCKET
        touch -f $PUMA_PID_FILE
        if [ -e $PUMA_CONFIG_FILE ] ; then
          bundle exec puma -C $PUMA_CONFIG_FILE
        else
          bundle exec puma
        fi

      echo "done"
      ;;

    stop)
      echo "Stopping puma..."
        kill -s SIGTERM `cat $PUMA_PID_FILE`
        rm -f $PUMA_PID_FILE
        rm -f $PUMA_SOCKET
      echo "done"
      ;;

    restart)
      if puma_is_running ; then
        echo "Hot-restarting puma..."
        kill -s SIGUSR2 `cat $PUMA_PID_FILE`

        echo "Doublechecking the process restart..."
        sleep 5
        if puma_is_running ; then
          echo "done"
          exit 0
        else
          echo "Puma restart failed :/"
        fi
      fi

      echo "Trying cold reboot"
      echo [ -S $PUMA_SOCKET ]
      bin/puma.sh start
      ;;

    *)
      echo "Usage: bin/puma.sh {start|stop|restart}" >&2
      ;;
  esac

配置Mina

  1. 在Gemfile中添加gem 'mina'
  2. mina init生成deploy.rb文件
  3. 设置myapp/config/deploy.rb
    require 'mina/bundler'
    require 'mina/rails'
    require 'mina/git'
    require 'mina/rvm'   

    set :user, 'deploy'
    set :domain, 'your.server.domain.ip'
    set :deploy_to, '/var/www/myapp'
    set :repository, 'https://github.com/YourGitName/myapp.git'
    set :branch, 'master'
    set :forward_agent, true
    set :app_path, lambda { "#{deploy_to}/#{current_path}" }
    set :stage, 'production'
    set :rvm_path, '/home/deploy/.rvm/bin/rvm'

    set :shared_paths, ['config/database.yml', 'log']

    task :environment do
      invoke :'rvm:use[ruby-2.0.0-p643@default]'
    end

    task :setup => :environment do
      queue! %[mkdir -p "#{deploy_to}/#{shared_path}/log"]
      queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/log"]

      queue! %[mkdir -p "#{deploy_to}/#{shared_path}/config"]
      queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/config"]
      
      queue! %[mkdir -p "#{deploy_to}/#{shared_path}/tmp"]
      queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/tmp"]
      
      queue! %[mkdir -p "#{deploy_to}/#{shared_path}/tmp/sockets"]
      queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/tmp/sockets"]
      
      queue! %[mkdir -p "#{deploy_to}/#{shared_path}/tmp/pids"]
      queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/tmp/pids"] 
      
      queue! %[mkdir -p "#{deploy_to}/#{shared_path}/tmp/log"]
      queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/tmp/log"] 
      
      queue! %[touch "#{deploy_to}/#{shared_path}/config/database.yml"]
      queue  %[echo "-----> Be sure to edit '#{deploy_to}/#{shared_path}/config/database.yml'."]
    end

    desc "Deploys the current version to the server."
    task :deploy => :environment do
      to :before_hook do
      end
      deploy do
        invoke :'git:clone'
        invoke :'deploy:link_shared_paths'
        invoke :'bundle:install'
        queue! "cd #{app_path} & RAILS_ENV=#{stage} bundle exec rake db:create"
        invoke :'rails:db_migrate'
        queue! "cd #{app_path} & RAILS_ENV=#{stage} bundle exec rake db:seed"
        invoke :'rails:assets_precompile'
        invoke :'deploy:cleanup'
        invoke :'puma:restart'

        to :launch do      
        end
      end
    end

    namespace :puma do 
      desc "Start the application"
      task :start do
        queue 'echo "-----> Start Puma"'  
        queue "cd #{app_path} && RAILS_ENV=#{stage} && bin/puma.sh start", :pty => false
      end

      desc "Stop the application"
      task :stop do
        queue 'echo "-----> Stop Puma"'
        queue "cd #{app_path} && RAILS_ENV=#{stage} && bin/puma.sh stop"
      end

      desc "Restart the application"
      task :restart do
        queue 'echo "-----> Restart Puma"'
        queue "cd #{app_path} && RAILS_ENV=#{stage} && bin/puma.sh restart"
      end
    end

开始部署

  1. Rails 相关设置

    1. 编辑/config/application.rb
    • config.assets.precompile += %w(....)在括号中加入app/assets/和lib/assets/还有vender/assets/里面js/css的文件
    1. 编辑/config/environments/production.rb
      • # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' 因为我们要用Nginx,所以要将此行应用。
  2. setup

  3. mina setup

- 在此过程中可能会遇到问题:
   1. 安装libv8失败:可以尝试`bundle config build.libv8 --with-system-v8`
   1. 安装nokogiri失败,可以尝试`bundle config build.nokogiri --use-system-li braries`
   1. 安装therubyracer失败,还没有找到有效的解决办法。
- 解决方案
   1. Gemfile去掉 `gem 'therubyracer'` 和 `gem 'less-rails'`
   2. `bundle install`
   3. 用nodejs代替libv8来提供Javascript运行时环境
  • 配置 /var/www/myapp/shared/config/database.yml
  • 将myapp/config/database.yml内容复制进去
  1. deploy

    • mina deploy
  2. Nginx设置

    1. 修改/etc/nginx/nginx.conf

            user  deploy;
            worker_processes  1;
      
            error_log  /var/log/nginx/error.log warn;
            pid        /var/run/nginx.pid;
      
            events {
                worker_connections  1024;
            }
      
            http {
                include       /etc/nginx/mime.types;
                default_type  application/octet-stream;
      
                log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                                  '$status $body_bytes_sent "$http_referer" '
                                  '"$http_user_agent" "$http_x_forwarded_for"';
      
                access_log  /var/log/nginx/access.log  main;
      
                sendfile        on;
                #tcp_nopush     on;
      
                keepalive_timeout  65;
      
                #gzip  on;
      
                include /etc/nginx/conf.d/*.conf;
                upstream deploy {
                        server unix:///var/www/myapp/tmp/sockets/puma.sock;
                }
      
                server {
                    listen 80;
                    server_name your.server.domain.ip; # change to match your URL
                    root /var/www/myapp/current/public; # I assume your app is located at this location 
                
                    location / {
                        proxy_pass http://deploy; # match the name of upstream directive which is defined above 
                        proxy_set_header Host $host; 
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    }   
                    
                    location ~* ^/assets/ {
                        # Per RFC2616 - 1 year maximum expiry
                        expires 1y; 
                        add_header Cache-Control public; 
                                # Some browsers still send conditional-GET requests if there's a
                        # Last-Modified header or an ETag header even if they haven't
                        # reached the expiry date sent in the Expires header.
                        add_header Last-Modified "";
                        add_header ETag "";
                        break;
                    }
                }
            }
      
  3. 重启nginx

    1. sudo nginx -s reload
后记

中间可能会遇到很多问题可以从以下几个方面进行排查

  1. 首先保证Puma在可以跑,

    1. 将config/puma.rb 里的 daemonize true注释掉
    2. 在/var/www/myapp/current目录里运行bundle exec puma -C config/puma.rb
  2. 查看/var/log/nginx/error.log看错误信息

    1. 可能会遇到Permission denied问题,注意/etc/nginx/nginx.conf文件第一行的user deploy
    2. 可能会遇到Connection refuesd问题,可能是Puma运行失败。
  3. 要有耐心,说实话第一次部署会遇到各种各样的问题,遇到很多不熟悉的知识点。在此过程中可以学到很多知识,加油吧。

你可能感兴趣的:(部署Rails CentOS6.5 ( Nginx+Puma+Mina ))