如何部署Rails应用程序与Unicorn和Nginx的在Ubuntu 14.04

当您准备on Rails应用程序部署的Ruby,有很多有效的设置需要考虑。本教程将帮助您部署的Ruby on Rails应用程序的生产环境,在PostgreSQL作为数据库,用Unicorn和Nginx的Ubuntu上...

介绍

当您准备好部署Ruby on Rails应用程序时,有许多有效的设置要考虑。 本教程将帮助您部署Ruby on Rails应用程序的生产环境,使用PostgreSQL作为数据库,在Ubuntu 14.04上使用Unicorn和Nginx。

Unicorn是一个应用服务器,如PassengerPuma ,使您的Rails应用程序可以并发处理的请求。 由于Unicorn不是设计为由用户直接访问,我们将使用Nginx作为反向代理,将缓冲用户和Rails应用程序之间的请求和响应。

先决条件

本教程假设您有一个Ubuntu 14.04服务器,安装了以下软件,将部署应用程序的用户:

如果您没有设置,请按照上面链接的教程。 我们假设你的用户称为部署

此外,本教程不介绍如何设置开发或测试环境。 如果你需要帮助,请按照PostgreSQL with Rails教程中的示例。

创建Rails应用程序

理想情况下,您已经有一个要部署的Rails应用程序。 如果是这种情况,您可以跳过此部分,并在跟随时进行适当的替换。 如果没有,第一步是创建一个使用PostgreSQL作为其数据库的新Rails应用程序。

此命令将创建一个名为“appname”的新Rails应用程序,它将使用PostgreSQL作为数据库。 随意替换突出显示的“appname”用别的东西:

rails new appname -d postgresql

然后切换到应用程序目录:

cd appname

让我们花一点时间来创建将由Rails应用程序的生产环境使用的PostgreSQL用户。

创建生产数据库用户

为了简单起见,让我们将生产数据库用户命名为应用程序名称。 例如,如果您的应用程序被称为“appname”,您应该创建一个PostgreSQL用户,如下所示:

sudo -u postgres createuser -s appname

我们要设置数据库用户的密码,因此输入PostgreSQL控制台如下:

sudo -u postgres psql

然后在示例中设置数据库用户的密码,“appname”,如下所示:

\password appname

输入所需的密码并确认。

使用以下命令退出PostgreSQL控制台:

\q

现在,我们准备好使用正确的数据库连接信息配置您的应用程序。

配置数据库连接

请确保你在你的应用程序的根目录( cd ~/ appname )。

在您喜欢的文本编辑器中打开应用程序的数据库配置文件。 我们将使用vi:

vi config/database.yml

根据default部分中,找到写着“池:5”的路线,并在其添加以下行(如果它不存在):

  host: localhost

如果您滚动到文件的底部,你会发现, production部分设置如下:

  username: appname
  password: <%= ENV['APPNAME_DATABASE_PASSWORD'] %>

如果您的生产用户名与先前创建的数据库用户不匹配,请立即进行设置。

注意,数据库口令被配置成由一个环境变量,被读取APPNAME _DATABASE_PASSWORD 将生产密码和秘密保留在应用程序代码库之外是最佳做法,因为如果您使用的是分布式版本控制系统(如Git),它们可以轻松暴露出来。 我们将讨论如何使用环境变量设置数据库认证。

安装rbenv-vars插件

在部署生产Rails应用程序之前,应该使用环境变量设置生产密钥和数据库密码。 一个简单的方法来管理环境变量,我们可以在运行时使用密码和秘密加载到我们的应用程序,是使用rbenv -瓦尔插件。

要安装rbenv -瓦尔插件,只需切换到.rbenv/plugins目录,并从GitHub克隆。 例如,如果rbenv安装在您的主目录中,请运行以下命令:

cd ~/.rbenv/plugins
git clone https://github.com/sstephenson/rbenv-vars.git

设置环境变量

现在安装了rbenv-vars插件,让我们设置所需的环境变量。

首先,生成秘密密钥,将用于验证签名的cookie的完整性:

cd ~/appname
rake secret

复制生成的密钥,然后打开.rbenv-vars用你喜欢的编辑器文件。 我们将使用vi:

vi .rbenv-vars

您在此设置的任何环境变量都可以由Rails应用程序读取。

首先,设置SECRET_KEY_BASE这样的变量(替换您刚才生成和复制的秘密高亮文本):

SECRET_KEY_BASE=your_generated_secret

接下来,设置APPNAME _DATABASE_PASSWORD这样的变量(与你的应用程序名称替换突出了“APPNAME”和“prod_db_pass”与您的生产数据库的用户密码):

APPNAME_DATABASE_PASSWORD=prod_db_pass

保存并退出。

您可以通过运行以下命令,使用rbenv-vars插件查看为应用程序设置的环境变量:

rbenv vars

如果你改变你的秘密,数据库密码,更新.rbenv-vars文件。 请小心保持此文件为私有,并且不要包含任何公共代码存储库。

创建生产数据库

现在您的应用程序配置为与您的PostgreSQL数据库通信,让我们创建生产数据库:

RAILS_ENV=production rake db:create

生成控制器

如果你跟着这个例子,我们将生成一个scaffold控制器,所以我们的应用程序将有一些东西看看:

rails generate scaffold Task title:string note:text

现在运行此命令来更新生产数据库:

RAILS_ENV=production rake db:migrate

预编译资源

在这一点上,应用程序应该工作,但您需要预编译其资产,以便加载任何图像,C​​SS和脚本。 为此,请运行以下命令:

RAILS_ENV=production rake assets:precompile

测试应用程序

要测试应用程序是否工作,可以运行生产环境,并将其绑定到服务器的公共IP地址(替换服务器的公共IP地址):

RAILS_ENV=production rails server --binding=server_public_IP

现在,在网络浏览器中访问此网址:

http://server_public_IP:3000/tasks

如果它正常工作,你应该看到这个页面:

任务控制器

回到你的Rails的服务器,然后按Ctrl-c停止应用程序。

安装Unicorn

现在我们准备安装Unicorn。

一个简单的方法做,这是将它添加到您的应用程序Gemfile 在您喜欢的编辑器中打开Gemfile(确保您在应用程序的根目录中):

vi Gemfile

在文件末尾,添加带有此行的UnicornGem:

gem 'unicorn'

保存并退出。

要安装Unicorn及任何未决的依赖关系,请运行Bundler:

bundle

Unicorn现在已经安装,但是我们需要配置它。

配置Unicorn

让我们添加Unicorn配置, config/unicorn.rb 在文本编辑器中打开文件:

vi config/unicorn.rb

将此配置复制并粘贴到文件中:

# set path to application
app_dir = File.expand_path("../..", __FILE__)
shared_dir = "#{app_dir}/shared"
working_directory app_dir


# Set unicorn options
worker_processes 2
preload_app true
timeout 30

# Set up socket location
listen "#{shared_dir}/sockets/unicorn.sock", :backlog => 64

# Logging
stderr_path "#{shared_dir}/log/unicorn.stderr.log"
stdout_path "#{shared_dir}/log/unicorn.stdout.log"

# Set master PID location
pid "#{shared_dir}/pids/unicorn.pid"

保存并退出。 这将为Unicorn配置应用程序的位置,以及套接字,日志和PID的位置。 随意修改文件,或添加您需要的任何其他选项。

现在创建配置文件中引用的目录:

mkdir -p shared/pids shared/sockets shared/log

创建Unicorn Init脚本

让我们创建一个初始化脚本,以便我们可以轻松地启动和停止Unicorn,并确保它将在启动时启动。

创建一个脚本并使用此命令打开它进行编辑(如果你愿意,用你的应用程序名称替换突出显示的部分):

sudo vi /etc/init.d/unicorn_appname

复制以下代码块粘贴到它,并确保替代USERAPP_NAME用适当的值(高亮):

#!/bin/sh

### BEGIN INIT INFO
# Provides:          unicorn
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the unicorn app server
# Description:       starts unicorn using start-stop-daemon
### END INIT INFO

set -e

USAGE="Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"

# app settings
USER="deploy"
APP_NAME="appname"
APP_ROOT="/home/$USER/$APP_NAME"
ENV="production"

# environment settings
PATH="/home/$USER/.rbenv/shims:/home/$USER/.rbenv/bin:$PATH"
CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D"
PID="$APP_ROOT/shared/pids/unicorn.pid"
OLD_PID="$PID.oldbin"

# make sure the app exists
cd $APP_ROOT || exit 1

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

oldsig () {
  test -s $OLD_PID && kill -$1 `cat $OLD_PID`
}

case $1 in
  start)
    sig 0 && echo >&2 "Already running" && exit 0
    echo "Starting $APP_NAME"
    su - $USER -c "$CMD"
    ;;
  stop)
    echo "Stopping $APP_NAME"
    sig QUIT && exit 0
    echo >&2 "Not running"
    ;;
  force-stop)
    echo "Force stopping $APP_NAME"
    sig TERM && exit 0
    echo >&2 "Not running"
    ;;
  restart|reload|upgrade)
    sig USR2 && echo "reloaded $APP_NAME" && exit 0
    echo >&2 "Couldn't reload, starting '$CMD' instead"
    $CMD
    ;;
  rotate)
    sig USR1 && echo rotated logs OK && exit 0
    echo >&2 "Couldn't rotate logs" && exit 1
    ;;
  *)
    echo >&2 $USAGE
    exit 1
    ;;
esac

保存并退出。 这将允许您使用service unicorn_ appname开始和停止你的Unicorn和Rails应用程序。

更新脚本的权限,并启用Unicorn在启动时启动:

sudo chmod 755 /etc/init.d/unicorn_appname
sudo update-rc.d unicorn_appname defaults

让我们开始吧:

sudo service unicorn_appname start

现在,您的Rails应用程序的生产环境下的Unicorn运行,它监听的shared/sockets/unicorn.sock插座。 在您的应用程序可供外部用户访问之前,您必须设置Nginx反向代理。

安装和配置Nginx

使用apt-get安装Nginx:

sudo apt-get install nginx

现在使用文本编辑器打开默认服务器块:

sudo vi /etc/nginx/sites-available/default

使用以下代码块替换文件的内容。 请务必使用适当的用户名和应用程序名称替换突出显示的部分:

upstream app {
    # Path to Unicorn SOCK file, as defined previously
    server unix:/home/deploy/appname/shared/sockets/unicorn.sock fail_timeout=0;
}

server {
    listen 80;
    server_name localhost;

    root /home/deploy/appname/public;

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

    location @app {
        proxy_pass http://app;
        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;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

保存并退出。 这将Nginx配置为反向代理,因此HTTP请求通过Unix套接字转发到Unicorn应用程序服务器。 随意地做任何更改,你认为合适。

重新启动Nginx以使更改生效:

sudo service nginx restart

现在您的Rails应用程序的生产环境可通过您的服务器的公共IP地址或FQDN访问。 要访问我们之前创建的任务控制器,请在Web浏览器中访问应用程序服务器:

http://server_public_IP/tasks

您应该看到您第一次测试应用程序时看到的相同页面,但现在它通过Nginx和Unicorn提供。

结论

恭喜! 您已经使用Nginx和Unicorn部署了您的Ruby on Rails应用程序的生产环境。

如果您正在寻找提高你的生产Rails应用程序的部署,你应该看看我们的教程系列如何使用Capistrano的来自动化部署 该系列基于CentOS,但它仍然有助于自动化您的部署。