1.5 部署

即使现在还处在早期阶段,我们还是要把(几乎没什么内容)的 Rails 应用部署到生产环境。这一步可做可不做,不过在开发过程中尽早且频繁地部署,可以尽早发现开发中的问题。在开发环境中花费大量精力之后再部署,往往会在发布时遇到严重的集成问题。[13]

以前,部署 Rails 应用是件痛苦的事。但最近几年,Rails 开发生态系统不断成熟,已经出现很多好的解决方案了,包括使用 Phusion Passenger(Apache 和 Nginx [14] Web 服务器的一个模块)的共享主机和虚拟私有服务器,Engine YardRails Machine 这种提供全方位部署服务的公司,以及 Engine Yard CloudNinefoldHeroku 这种云部署服务。

我最喜欢使用 Heroku 部署 Rails 应用。Heroku 专门用于部署 Rails 和其他 Web 应用,部署 Rails 应用的过程异常简单——只要源码纳入了 Git 版本控制系统就好。(这也是为什么要按照 1.4 节介绍的步骤设置 Git。如果你还没有照着做,现在赶紧做吧。)本节下面的内容专门介绍如何把我们的第一个应用部署到 Heroku 中。其中一些操作相对高级,如果没有完全理解也不要紧。本节的重点是把应用部署到线上环境中。

1.5.1 搭建 Heroku 部署环境

Heroku 使用 PostgreSQL[15] 数据库,所以我们要把 pg 加入生产组,这样 Rails 才能和 PostgreSQL 通信:[16]

group :production do
  gem 'pg',             '0.17.1'
  gem 'rails_12factor', '0.0.2'
end

注意,我们还添加了 rails_12factor,Heroku 使用这个 gem 伺服静态资源,例如图片和样式表。另外,要加入代码清单 1.5 所做的改动,避免在生产环境安装 sqlite3 gem,这是因为 Heroku 不支持 SQLite。

group :development, :test do
  gem 'sqlite3',     '1.3.9'
  gem 'byebug',      '3.4.0'
  gem 'web-console', '2.0.0.beta3'
  gem 'spring',      '1.1.3'
end

最终得到的 Gemfile代码清单 1.14 所示。

代码清单 1.14:增加 gem 后的 Gemfile
source 'https://rubygems.org'

gem 'rails',                '4.2.2'
gem 'sass-rails',           '5.0.2'
gem 'uglifier',             '2.5.3'
gem 'coffee-rails',         '4.1.0'
gem 'jquery-rails',         '4.0.3'
gem 'turbolinks',           '2.3.0'
gem 'jbuilder',             '2.2.3'
gem 'sdoc',                 '0.4.0', group: :doc

group :development, :test do
  gem 'sqlite3',     '1.3.9'
  gem 'byebug',      '3.4.0'
  gem 'web-console', '2.0.0.beta3'
  gem 'spring',      '1.1.3'
end

group :production do
 gem 'pg',             '0.17.1' gem 'rails_12factor', '0.0.2' end

为了准备好部署环境,下面要运行 bundle install 命令,并且指定一个特殊的选项,禁止在本地安装生产环境使用的 gem(即 pgrails_12factor):

$ bundle install --without production

因为我们在代码清单 1.14 中只添加了用于生产环境的 gem,所以现在执行这个命令其实不会在本地安装任何新的 gem,但是又必须执行这个命令,因为我们要把 pgrails_12factor 添加到 Gemfile.lock 中。然后提交这次改动:

$ git commit -a -m "Update Gemfile.lock for Heroku"

接下来我们要注册并配置一个 Heroku 新账户。第一步是注册 Heroku 账户。然后检查系统中是否已经安装 Heroku 命令行客户端:

$ heroku version

使用云端 IDE 的读者应该会看到 Heroku 客户端的版本号,这表明可以使用命令行工具 heroku。在其他系统中,可能需要使用 Heroku Toolbelt 安装。

确认 Heroku 命令行工具已经安装之后,使用 heroku 命令登录,然后添加 SSH 密钥:

$ heroku login
$ heroku keys:add

最后,执行 heroku create 命令,在 Heroku 的服务器中创建一个文件夹,用于存放演示应用,如代码清单 1.15 所示。

代码清单 1.15:在 Heroku 中创建一个新应用
$ heroku create Creating damp-fortress-5769... done, stack is cedar
http://damp-fortress-5769.herokuapp.com/ | [email protected]:damp-fortress-5769.git
Git remote heroku added

heroku 命令会为你的应用分配一个二级域名,立即生效。当然,现在还看不到内容,我们开始部署吧。

1.5.2 Heroku 部署第一步

部署应用的第一步是,使用 Git 把主分支推送到 Heroku 中:

$ git push heroku master

(可能会看到一些提醒消息,现在先不管,7.5 节会解决。)

1.5.3 Heroku 部署第二步

其实没有第二步了。我们已经完成部署了。现在可以通过 heroku create 命令给出的地址(参见代码清单 1.15,如果没用云端 IDE,在本地可以执行 heroku open 命令)查看刚刚部署的应用,如图 1.18 所示。看到的页面和图 1.12 一样,但是现在这个应用运行在生产环境中。

heroku app hello world图 1.18:运行在 Heroku 中的第一个应用

1.5.4 Heroku 命令

Heroku 提供了很多命令,本书只简单介绍了几个。下面花几分钟再介绍一个命令,其作用是重命名应用:

$ heroku rename rails-tutorial-hello

你别再使用这个名字了,我已经占用了。或许,现在你无需做这一步,使用 Heroku 提供的默认地址就行。不过,如果你真想重命名应用,基于安全考虑,可以使用一些随机或难猜到的二级域名,例如:

hwpcbmze.herokuapp.com
seyjhflo.herokuapp.com
jhyicevg.herokuapp.com

使用这样随机的二级域名,只有你将地址告诉别人他们才能访问你的网站。顺便让你一窥 Ruby 的强大,下面是我用来生成随机二级域名的代码,很精妙吧。

('a'..'z').to_a.shuffle[0..7].join

除了支持二级域名,Heroku 还支持自定义域名。其实本书的网站[17]就放在 Heroku 中。如果你阅读的是在线版,现在就在浏览一个托管于 Heroku 中的网站。在 Heroku 文档中可以查看更多关于自定义域名的信息以及 Heroku 相关的其他话题。