7.5 专业部署方案
现在注册页面可以使用了,该把应用部署到生产环境了。虽然我们从第 3 章就开始部署了,但现在应用才真正有点用,所以借此机会我们要把部署过程变得更专业一些。具体而言,我们要在生产环境的应用中添加一个重要功能,保障注册过程的安全性,还要把默认的 Web 服务器换成一个更适合在真实环境中使用的服务器。
为了部署,现在你应该把改动合并到 master
分支中:
$ git add -A
$ git commit -m "Finish user signup"
$ git checkout master
$ git merge sign-up
7.5.1 在生产环境中使用 SSL
在本章开发的注册表单中提交数据注册用户时,用户的名字、电子邮件地址和密码会在网络中传输,因此可能在途中被拦截。这是应用的重大潜在安全隐患,解决的方法是使用“安全套接层”(Secure Sockets Layer,简称 SSL),[12]在数据离开浏览器之前加密相关信息。我们可以只在注册页面启用 SSL,不过整站启用也容易实现。整站都启用 SSL 后,第 8 章实现的用户登录功能也能从中受益,而且还能防范 8.4 节讨论的会话劫持。
启用 SSL 很简单,只要在生产环境的配置文件 production.rb
中去掉一行代码的注释即可。如代码清单 7.27 所示,我们只需设置 config
变量,强制在生产环境中使用 SSL。
代码清单 7.27:配置应用,在生产环境中使用 SSL
config/environments/production.rb
Rails.application.configure do
.
.
.
# Force all access to the app over SSL, use Strict-Transport-Security,
# and use secure cookies.
config.force_ssl = true .
.
.
end
然后,我们要在远程服务器中设置 SSL。这个过程包括为自己的域名购买和设置 SSL 证书,有很多工作要做。不过幸运的是,我们并不需要处理这些事,因为在 Heroku 中运行的应用(例如我们的演示应用),可以直接使用 Heroku 的 SSL 证书。所以,7.5.2 节部署应用后,会自动启用 SSL。(如果你想在自己的域名上使用 SSL,例如 www.example.com
,参照 Heroku 对 SSL 的说明。)
7.5.2 生产环境中的 Web 服务器
启用 SSL 后,我们要配置应用,让它使用一个适合在生产环境中使用的 Web 服务器。默认情况下,Heroku 使用纯 Ruby 实现的 WEBrick,这个服务器易于搭建,但不能很好地处理巨大流量。因此,WEBrick 不适合在生产环境中使用,我们要换用能处理大量请求的 Puma。
我们按照 Heroku 文档中的说明,换用 Puma。第一步,在 Gemfile
中添加 puma
gem,如代码清单 7.28 所示。因为在本地不需要使用 Puma,所以我们把 puma
放在 :production
组中。
代码清单 7.28:在 Gemfile
中添加 Puma
source 'https://rubygems.org'
.
.
.
group :production do
gem 'pg', '0.17.1'
gem 'rails_12factor', '0.0.2'
gem 'puma', '2.11.1' end
因为我们配置过 Bundler,不让它安装生产环境的 gem(3.1 节),所以代码清单 7.28 不会在开发环境中安装额外的 gem,不过我们还是要运行 Bundler,更新 Gemfile.lock
:
$ bundle install
下一步是创建文件 config/puma.rb
,然后写入代码清单 7.29 中的内容。这段代码直接摘自 Heroku 的文档,[13]没必要理解它的意思。
代码清单 7.29:生产环境所用 Web 服务器的配置文件
config/puma.rb
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Rails 4.1+ 专用的职程设置
# 详情参见:https://devcenter.heroku.com/articles/
# deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end
最后,我们要新建一个 Procfile
文件,告诉 Heroku 在生产环境运行一个 Puma 进程。这个文件的内容如代码清单 7.30 所示。Procfile
文件和 Gemfile
文件一样,应该放在应用的根目录中。
代码清单 7.30:创建 Puma 需要的 Procfile
文件
./Procfile
web: bundle exec puma -C config/puma.rb
生产环境的 Web 服务器配置好之后,我们可以提交并部署了:[14]
$ bundle exec rake test
$ git add -A
$ git commit -m "Use SSL and the Puma webserver in production"
$ git push
$ git push heroku
$ heroku run rake db:migrate
现在,注册页面可以在生产环境中使用了,注册成功后显示的页面如图 7.24。注意图中的地址栏,使用的是 https://
,而且还有一个锁状图标——表明启用了 SSL。
图 7.24:在生产环境中注册
7.5.3 Ruby 的版本
部署到 Heroku 时,可能会看到类似下面的提醒消息:
###### WARNING:
You have not declared a Ruby version in your Gemfile.
To set your Ruby version add this line to your Gemfile:
ruby '2.1.5'
经验表明,对本书面向的读者来说,明确指定 Ruby 的版本号要做很多额外工作,得不偿失,[15]所以现在你应该忽略这个提醒。为了让演示应用和系统中的 Ruby 版本保持最新,会遇到很多问题,而且不同的版本之间没有太大的差异。不过要记住,如果想在 Heroku 中运行重要的应用,建议在 Gemfile
中明确指定 Ruby 版本号,尽量减少开发环境和生产环境之间的差异。