如何在Ubuntu 14.04上使用Unicorn和Nginx部署Rails应用程序

介绍

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

Unicorn是一个应用服务器,就像Passenger或者Puma一样,它使您的Rails应用程序能够同时处理请求。由于Unicorn不是设计成能够直接被用户访问的,所以我们将使用Nginx作为反向代理,它将缓冲用户和Rails应用程序之间的请求和响应。

教程准备

本教程假定您将在部署应用程序的用户上安装了安装了以下软件的Ubuntu 14.04服务器(没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器 ):

  • Ruby on Rails, using rbenv
  • PostgreSQL with Rails

我们假设您的用户名为 deploy

此外,本教程未介绍如何设置开发或测试环境。如果您需要帮助,请参考腾讯云+社区中有关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部分下,找到显示“pool:5”的行并在其下添加以下行(如果它尚不存在):

  host: localhost

如果滚动到文件的底部,您会注意到该production部分设置如下:

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

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

请注意,数据库密码配置为由环境变量APPNAME_DATABASE_PASSWORD读取。将生产密码和机密保存在应用程序代码库之外被认为是最佳实践,因为如果您使用的是分布式版本控制系统(如Git)时,它们会很容易被暴露出来。接下来我们将讨论如何使用环境变量设置数据库身份验证。

安装rbenv-vars插件

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

要安装rbenv-vars插件,只需更改到.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

生成控制器

如果您跟随示例,我们将生成一个脚手架控制器,以便我们的应用程序可以查看它:

rails generate scaffold Task title:string note:text

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

RAILS_ENV=production rake db:migrate

预编译资产

此时,应用程序应该可以工作,但您需要预编译其资产,以便该程序可以加载任何图像,CSS和脚本。为此,请运行以下命令:

RAILS_ENV=production rake assets:precompile

测试应用

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

RAILS_ENV=production rails server --binding=server_public_IP

现在,在Web浏览器中访问此URL:

http://server_public_IP:3000/tasks

如果它正常工作,您应该看到此页面:

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

安装Unicorn

现在我们准备安装Unicorn了。

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

vi Gemfile

在文件的末尾,使用以下行添加Unicorn gem:

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脚本

让我们创建一个init脚本,这样我们就可以轻松启动和停止Unicorn,并确保它将在程序启动时启动。

使用此命令创建一个脚本并打开它进行编辑(如果您愿意,用您的应用程序名称替换appname):

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

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

http://server_public_IP/tasks

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

结论

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

如果您希望改进生产Rails应用程序部署,您应该查看我们的如何使用Capistrano自动部署的教程系列。该系列基于CentOS,但它仍然有助于自动化部署。

更多Ubuntu教程请前往腾讯云+社区学习更多知识。


参考文献:《How To Deploy a Rails App with Unicorn and Nginx on Ubuntu 14.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏SpringBoot 核心技术

第二十四章:SpringBoot项目整合JPA多数据源配置

49140
来自专栏云计算教程系列

如何在CentOS 7上安装MySQL

MySQL是一个开源数据库管理系统,通常情况下,安装它作为流行的LEMP(Linux,Nginx,MySQL/ MariaDB,PHP / Python /Pe...

46940
来自专栏IT技术精选文摘

浅析Nginx的工作模式及原理

(微信公众号:IT技术精选文摘, 微信号:ITHK01, 欢迎订阅) 同Apache http server的Perfork工作模型类似,Nginx也有mast...

70970
来自专栏云计算教程系列

如何在Ubuntu 16.04上安装Bro

Bro是一个开源网络分析框架和安全监控应用程序。它将OSSEC和osquery的一些最佳功能集成到一个包中。

24550
来自专栏云计算教程系列

如何在Debian 8上安装Munin监视工具

Munin是一个系统,网络和基础设施监控应用程序,通过Web浏览器以图形形式提供信息。它是围绕客户端 - 服务器架构设计的,可以配置为监控它所安装的机器(Mun...

7100
来自专栏木制robot技术杂谈

懒人神器 autoenv

前言 每次去不同的项目下运行程序都要更改相对应的 Python 环境,那么有什么办法可以省去这繁琐的一步吗?答案肯定是有的,Kenneth Reitz 已经为我...

45160
来自专栏Django Scrapy

Ubuntu默认防火墙安装、启用、配置、端口、查看状态相关信息

最简单的一个操作: sudo ufw status(如果你是root,则去掉sudo,ufw status)可检查防火墙的状态,我的返回的是:inactive(...

93660
来自专栏小樱的经验随笔

Linux目录结构

Linux 目录结构 装完Linux,首先需要弄清Linux 标准目录结构 ? / root —?启动Linux时使用的一些核心文件。如操作系统内核、引导程序G...

49760
来自专栏云计算教程系列

如何在Ubuntu 14.04上安装Munin监视工具

Munin是一个系统,网络和基础设施监控应用程序,通过Web浏览器以图形形式提供信息。它是围绕客户端 - 服务器架构设计的,可以配置为监控它所安装的机器(Mun...

13200
来自专栏云计算教程系列

如何在Ubuntu 18.04上安装和配置Postfix

Postfix是一种流行的开源邮件传输代理(MTA),可用于在Linux系统上路由和传递电子邮件。据估计,互联网上约有25%的公共邮件服务器运行Postfix。

34710

扫码关注云+社区

领取腾讯云代金券