部署 成功部署应用在 CentOS 6.3 + Nginx + Unicorn

dothide · 2013年12月19日 · 最后由 Martin91 回复于 2014年01月07日 · 5718 次阅读

哈哈,经过两天的学习终于成功部署了应用,在这里留个笔记,也算对得起两天没睡觉了。

服务器配置:CentOS 6.3 + Nginx + Unicorn Ruby 环境为:ruby 2.0.0 + rails 4.0.2 生产数据库为:MySQL 我的网站目录:/datas/ruby/dothide

软件安装我就不记了,网上有很多的

一、配置

1.首先在网站目录下的 config 文件夹下新建 unicorn.rb,并添加以下内容:

module Rails
  class <<self
    def root
      File.expand_path(__FILE__).split('/')[0..-3].join('/')
    end
  end
end
rails_env = ENV["RAILS_ENV"] || "production"

preload_app true
working_directory Rails.root
pid "#{Rails.root}/tmp/pids/unicorn.pid"
stderr_path "#{Rails.root}/log/unicornerr.log"
stdout_path "#{Rails.root}/log/unicornout.log"

listen 5000, :tcp_nopush => false

# 这里设置监听地址,将与nginx配置关联
listen "/tmp/unicorn.dothide.sock"
worker_processes 6
timeout 120

if GC.respond_to?(:copy_on_write_friendly=)
  GC.copy_on_write_friendly = true
end

before_fork do |server, worker|
  old_pid = "#{Rails.root}/tmp/pids/unicorn.pid.oldbin"
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      puts "Send 'QUIT' signal to unicorn error!"
    end
  end
end

2.在/etc/init.d/目录下执行以下命令新建 unicorn.dothide 文件,并添加以下内容:

#! /bin/sh
set -e

# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}

# 这里设置网站目录
APP_ROOT=/datas/ruby/dothide/
APP_USER=root
PID=$APP_ROOT/tmp/pids/unicorn.pid
ENV=production
CMD="bundle exec unicorn_rails -E $ENV -D -c $APP_ROOT/config/unicorn.rb"
action="$1"
set -u

old_pid="$PID.oldbin"
cd $APP_ROOT || exit 1

sig (){
        test -s "$PID" && kill -$1 `cat $PID`
}

oldsig (){
        test -s $old_pid && kill -$1 `cat $old_pid`
}
case $action in
start)
        sig 0 && echo >&2 "Already running" && exit 0
        su $APP_USER -c "$CMD"
        ;;
stop)
        sig QUIT && exit 0
        echo >&2 "Not running"
        ;;
force-stop)
        sig TERM && exit 0

        echo >&2 "Not running"
        ;;
restart|reload)
        sig HUP && echo reloaded OK && exit 0
        echo >&2 "Couldn't reload, starting '$CMD' instead"
        su $APP_USER -c "$CMD"
        ;;
upgrade)
        if sig USR2 && sleep2 && sig 0 && oldsig QUIT
        then
                n=$TIMEOUT
                while test -s $old_pid && test $n -ge 0
                do
                        printf '.' && sleep 1 && n=$(($n - 1))
                done
                echo

                if test $n -lt 0 && test -s $old_pid
                then
                        echo >&2 "$old_pid still exists after $TIMEOUT seconds"
                        exit1
                fi
                exit0
        fi
        echo >&2 "Couldn't upgrade, starting '$CMD' instead"
        su $APP_USER -c "$CMD"
        ;;
reopen-logs)
        sig USR1
        ;;*)
        echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
        exit 1
        ;;
esac

3.然后执行以下命令,将其转为可执行文件:

$ chmod +x /etc/init.d/unicorn.dothide

4.Nginx 配置如下:

...

upstream dothide_backend {
    server unix://tmp/unicorn.dothide.sock fail_timeout=0;
}

server {
    listen 80;
    server_name dothide.domain.com
    index index.html
    # 必须指定到public目录
    root /datas/ruby/dothide/public

    include none.conf

    location / {
        proxy_redirect off;
        proxy_set_header  Host $host;
        proxy_set_header  X-Forwarded-Host $host;
        proxy_set_header  X-Forwarded-Server $host;
        proxy_set_header  X-Real-IP $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_buffering   on;
        proxy_pass        http://dothide_backend;
    }

    location ~ ^/(assets|images|javascripts|system)/ {
        root  /datas/ruby/dothide/public;
        expires max;
        break;
    }

    # access_log /datas/wwwlogs/dothide.domain.com.log dothide.domain.com
}

二、部署

1.先到网站目录下,执行以下命令:

$ bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin --deployment

2.组件安装完成之后,执行以下命令:

$ rake assets:precompile

以上命令将在 public/assets 目录下生成两个资源文件:application+MD5.js 和 application+MD5.css

3.生成资源文件后,执行以下命令:

$ rake db:migrate RAILS_ENV="production"

以上命令指定在生产数据库中建表

4.快乐地启动 Unicorn 服务器及 Nginx 服务器吧

$ /etc/init.d/unicorn.dothide (re)start
$ /etc/init.d/nginx (re)start

@dothide 感谢分享。我按照以上步奏走了一遍,restart unicorn 和 nginx 后,主页显示 403 Forbidden。请问你在部署时是否遇到同样的问题?谢谢

你应该谈一谈部署当中你遇到了哪些问题,哪些坑。这些总结网上还是有很多的,更多的愿意看到坑。我已经把网站从 Unicorn 上迁移到了 PUMA,效果还不错。

请教一下@jianpanxiu 从 Unicorn 上迁移到了 PUMA 的动机是什么呢,据我所知 Github 仍运行在 Unicorn 上

建议你再研究一下 capistrano https://github.com/capistrano/capistrano,程序总要修改,部署自动化很重要。

#4 楼 @vincent 嗯 加上 capistrano 才上档次 呵呵

请教一下 @vincent @Magic capistrano 与 mina,是否更推荐 capistrano?

#6 楼 @tomlive mina 没有用过,capistrano 用着很不错,应该说是 ruby 项目部署的标准了,ruby-china 就是用的 capistrano,它的配置文件 config/deploy.rb 可以作为参考。

#6 楼 @tomlive 刚开始用的话不需要考虑太多,两个做的东西都差不多,先学其中一个,另一个自然就好上手了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号