介绍
当你准备好部署你的Ruby on Rails应用程序时,有很多有效的设置要考虑。本教程将帮助你部署你的Ruby on Rails应用程序的生产环境,使用PostgreSQL作为数据库,在Ubuntu 14.04上使用Unicorn和Nginx。
独角兽是一个应用程序服务器,如Passenger或Puma,它使你的铁路应用程序能够同时处理请求. 由于"独角兽"并非设计为用户直接访问,我们将使用Nginx作为反向代理,在用户与你的"铁路"应用程序之间缓冲请求和响应.
前提条件
本教程假设您有一个 Ubuntu 14.04 服务器,安装了以下软件,在将部署应用程序的用户:
如果您尚未安装此设置,请遵循上文链接的教程,我们将假设您的用户名为 deploy 。
此外,本教程不涵盖如何设置您的开发或测试环境. 如果您需要帮助,请遵循 PostgreSQL with Rails 教程中的示例。
创建 Rails 应用程序
理想情况下,您已经拥有您想要部署的 Rails 应用程序。如果是这样的情况,您可以跳过本节,并在跟进过程中进行适当的替换。
此命令将创建一个新的 Rails 应用程序,名为appname
,将使用 PostgreSQL 作为数据库。
1rails new appname -d postgresql
然后转到应用程序目录:
1cd appname
让我们花一点时间来创建PostgreSQL用户,该用户将被您的Rails应用程序的生产环境使用。
创建生产数据库用户
为了让事情简单,让我们将生产数据库用户命名为你的应用程序名称,例如,如果你的应用程序被称为appname
,你应该创建一个 PostgreSQL 用户,如下:
1sudo -u postgres createuser -s appname
我们要设置数据库用户的密码,所以输入 PostgreSQL 控制台如下:
1sudo -u postgres psql
然后为数据库用户设置密码,appname
在示例中,如下:
1\password appname
输入您想要的密码并确认它。
使用此命令退出 PostgreSQL 控制台:
1\q
现在,我们已经准备好将您的应用程序配置为适当的数据库连接信息。
配置数据库连接
确保您位于应用程序的根目录(cd ~/appname
)。
在您最喜欢的文本编辑器中打开应用程序的数据库配置文件. 我们将使用 vi:
1vi config/database.yml
在):
1host: localhost
如果你滚到文件的底部,你会注意到生产
部分设置如下:
1username: appname
2 password: <%= ENV['APPNAME_DATABASE_PASSWORD'] %>
如果您的生产用户名不匹配您之前创建的数据库用户,请现在设置它。
请注意,数据库密码被配置为由环境变量读取,‘APPNAME_DATABASE_PASSWORD’. 将生产密码和秘密保存在应用程序代码库之外的最佳做法,因为如果您使用Git等分布式版本控制系统,它们可以很容易地暴露。
安装 rbenv-vars 插件
在部署生产 Rails 应用程序之前,您应该使用环境变量设置生产秘密密钥和数据库密码. 一个简单的方法来管理环境变量,我们可以在运行时将密码和秘密加载到我们的应用程序中,是使用 rbenv-vars 插件。
要安装 rbenv-vars 插件,只需转到 .rbenv/plugins
目录并从 GitHub 克隆它。
1cd ~/.rbenv/plugins
2git clone https://github.com/sstephenson/rbenv-vars.git
设置环境变量
现在安装了 rbenv-vars 插件,让我们设置所需的环境变量。
首先,生成秘密密钥,该密钥将用于验证已签名的cookie的完整性:
1cd ~/appname
2rake secret
复制生成的秘密密密钥,然后使用您最喜欢的编辑器打开 .rbenv-vars
文件。
1vi .rbenv-vars
您在这里设置的任何环境变量都可以通过您的 Rails 应用程序读取。
首先,将):
1SECRET_KEY_BASE=your_generated_secret
接下来,将):
1APPNAME_DATABASE_PASSWORD=prod_db_pass
保存和退出。
您可以通过运行此命令查看哪些环境变量为您的应用程序设置了 rbenv-vars 插件:
1rbenv vars
如果你更改了你的秘密密码或数据库密码,请更新你的 `.dll 文件. 请小心保持这个文件私密,不要包括任何公共代码存储库。
创建生产数据库
现在您的应用程序已配置为与您的 PostgreSQL 数据库进行交谈,让我们创建生产数据库:
1RAILS_ENV=production rake db:create
创建控制器
如果您跟随示例,我们将生成一个支架控制器,所以我们的应用程序将有东西要看:
1rails generate scaffold Task title:string note:text
现在运行此命令来更新生产数据库:
1RAILS_ENV=production rake db:migrate
预装资产
在此时,该应用程序应该工作,但您需要预编译其资产,以便任何图像,CSS和脚本加载。
1RAILS_ENV=production rake assets:precompile
测试应用程序
要测试您的应用程序是否有效,您可以运行生产环境,并将其绑定到您的服务器的公共IP地址(取代您的服务器的公共IP地址):
1RAILS_ENV=production rails server --binding=server_public_IP
现在,请在 Web 浏览器中访问此 URL:
1http://server_public_IP:3000/tasks
如果它正常工作,你应该看到这个页面:
回到您的 Rails 服务器,然后按Ctrl-c
来停止应用程序。
安装独角兽
现在我们已经准备好安装Unicorn了。
一个简单的方法是将其添加到您的应用程序的):
1vi Gemfile
在文件的末尾,添加这个行的独角兽宝石:
1gem 'unicorn'
保存和退出。
要安装 Unicorn 和任何突出的依赖,请运行 Bundler:
1bundle
现在Unicorn已安装,但我们需要配置它。
配置独角兽
让我们将我们的独角兽配置添加到 config/unicorn.rb
. 在文本编辑器中打开文件:
1vi config/unicorn.rb
复制并粘贴此配置到文件中:
1# set path to application
2app_dir = File.expand_path("../..", __FILE__)
3shared_dir = "#{app_dir}/shared"
4working_directory app_dir
5
6# Set unicorn options
7worker_processes 2
8preload_app true
9timeout 30
10
11# Set up socket location
12listen "#{shared_dir}/sockets/unicorn.sock", :backlog => 64
13
14# Logging
15stderr_path "#{shared_dir}/log/unicorn.stderr.log"
16stdout_path "#{shared_dir}/log/unicorn.stdout.log"
17
18# Set master PID location
19pid "#{shared_dir}/pids/unicorn.pid"
保存和退出. 这将 Unicorn 配置为您的应用程序的位置,以及其插槽,日志和 PID 的位置. 请自由修改文件,或添加您需要的任何其他选项。
现在创建在配置文件中提到的目录:
1mkdir -p shared/pids shared/sockets shared/log
创建 Unicorn Init 脚本
让我们创建一个 init 脚本,以便我们可以轻松启动和停止 Unicorn,并确保它在启动时启动。
创建一个脚本,并使用此命令打开它进行编辑(如果您想要的话,将突出部分替换为应用程序名称):
1sudo vi /etc/init.d/unicorn_appname
复制并粘贴以下代码块,并确保用相应的值代替):
1#!/bin/sh
2
3### BEGIN INIT INFO
4# Provides: unicorn
5# Required-Start: $all
6# Required-Stop: $all
7# Default-Start: 2 3 4 5
8# Default-Stop: 0 1 6
9# Short-Description: starts the unicorn app server
10# Description: starts unicorn using start-stop-daemon
11### END INIT INFO
12
13set -e
14
15USAGE="Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"
16
17# app settings
18USER="deploy"
19APP_NAME="appname"
20APP_ROOT="/home/$USER/$APP_NAME"
21ENV="production"
22
23# environment settings
24PATH="/home/$USER/.rbenv/shims:/home/$USER/.rbenv/bin:$PATH"
25CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D"
26PID="$APP_ROOT/shared/pids/unicorn.pid"
27OLD_PID="$PID.oldbin"
28
29# make sure the app exists
30cd $APP_ROOT || exit 1
31
32sig () {
33 test -s "$PID" && kill -$1 `cat $PID`
34}
35
36oldsig () {
37 test -s $OLD_PID && kill -$1 `cat $OLD_PID`
38}
39
40case $1 in
41 start)
42 sig 0 && echo >&2 "Already running" && exit 0
43 echo "Starting $APP_NAME"
44 su - $USER -c "$CMD"
45 ;;
46 stop)
47 echo "Stopping $APP_NAME"
48 sig QUIT && exit 0
49 echo >&2 "Not running"
50 ;;
51 force-stop)
52 echo "Force stopping $APP_NAME"
53 sig TERM && exit 0
54 echo >&2 "Not running"
55 ;;
56 restart|reload|upgrade)
57 sig USR2 && echo "reloaded $APP_NAME" && exit 0
58 echo >&2 "Couldn't reload, starting '$CMD' instead"
59 $CMD
60 ;;
61 rotate)
62 sig USR1 && echo rotated logs OK && exit 0
63 echo >&2 "Couldn't rotate logs" && exit 1
64 ;;
65 *)
66 echo >&2 $USAGE
67 exit 1
68 ;;
69esac
这将允许您使用服务 unicorn_appname
来启动和停止您的 Unicorn 和 Rails 应用程序。
更新脚本的权限,并允许 Unicorn 启动:
1sudo chmod 755 /etc/init.d/unicorn_appname
2sudo update-rc.d unicorn_appname defaults
让我们现在开始吧:
1sudo service unicorn_appname start
现在,您的 Rails 应用程序的生产环境在 Unicorn 下运行,并在shared/sockets/unicorn.sock
接口上收听。
安装和配置 Nginx
使用 apt-get 安装 Nginx:
1sudo apt-get install nginx
现在用文本编辑器打开默认服务器块:
1sudo vi /etc/nginx/sites-available/default
用以下代码块替换文件的内容. 请确保用相应的用户名和应用程序名称替换所突出的部分:
1upstream app {
2 # Path to Unicorn SOCK file, as defined previously
3 server unix:/home/deploy/appname/shared/sockets/unicorn.sock fail_timeout=0;
4}
5
6server {
7 listen 80;
8 server_name localhost;
9
10 root /home/deploy/appname/public;
11
12 try_files $uri/index.html $uri @app;
13
14 location @app {
15 proxy_pass http://app;
16 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
17 proxy_set_header Host $http_host;
18 proxy_redirect off;
19 }
20
21 error_page 500 502 503 504 /500.html;
22 client_max_body_size 4G;
23 keepalive_timeout 10;
24}
这将 Nginx 配置为反向代理,以便HTTP请求通过Unix插件传送到Unicorn应用程序服务器。
重新启动 Nginx 以执行这些更改:
1sudo service nginx restart
现在,您的 Rails 应用程序的生产环境可以通过您的服务器的公共 IP 地址或 FQDN 访问。
1http://server_public_IP/tasks
您应该看到您第一次测试应用程序时所看到的相同页面,但现在它正在通过 Nginx 和 Unicorn 服务。
结论
恭喜您!您已经部署了使用 Nginx 和 Unicorn 的 Ruby on Rails 应用程序的生产环境。
如果你想改进你的生产 Rails 应用程序部署,你应该检查我们的教程系列在 如何使用 Capistrano 自动部署. 该系列是基于CentOS,但它仍然应该有助于自动化你的部署。