# 7.5 专业部署方案
现在注册页面可以使用了,该把应用部署到生产环境了。虽然我们从[第 3 章](chapter3.html#mostly-static-pages)就开始部署了,但现在应用才真正有点用,所以借此机会我们要把部署过程变得更专业一些。具体而言,我们要在生产环境的应用中添加一个重要功能,保障注册过程的安全性,还要把默认的 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](#fn-12)]在数据离开浏览器之前加密相关信息。我们可以只在注册页面启用 SSL,不过整站启用也容易实现。整站都启用 SSL 后,[第 8 章](chapter8.html#log-in-log-out)实现的用户登录功能也能从中受益,而且还能防范 [8.4 节](chapter8.html#remember-me)讨论的会话劫持。
启用 SSL 很简单,只要在生产环境的配置文件 `production.rb` 中去掉一行代码的注释即可。如[代码清单 7.27](#listing-ssl-in-production) 所示,我们只需设置 `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 节](#production-webserver)部署应用后,会自动启用 SSL。(如果你想在自己的域名上使用 SSL,例如 `www.example.com`,参照 [Heroku 对 SSL 的说明](http://devcenter.heroku.com/articles/ssl)。)
## 7.5.2 生产环境中的 Web 服务器
启用 SSL 后,我们要配置应用,让它使用一个适合在生产环境中使用的 Web 服务器。默认情况下,Heroku 使用纯 Ruby 实现的 WEBrick,这个服务器易于搭建,但不能很好地处理巨大流量。因此,[WEBrick 不适合在生产环境中使用](https://devcenter.heroku.com/articles/ruby-default-web-server),我们要[换用能处理大量请求的 Puma](https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server)。
我们按照 [Heroku 文档中的说明](https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server),换用 Puma。第一步,在 `Gemfile` 中添加 `puma` gem,如[代码清单 7.28](#listing-puma-gemfile) 所示。因为在本地不需要使用 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 节](chapter3.html#sample-app-setup)),所以[代码清单 7.28](#listing-puma-gemfile) 不会在开发环境中安装额外的 gem,不过我们还是要运行 Bundler,更新 `Gemfile.lock`:
```
$ bundle install
```
下一步是创建文件 `config/puma.rb`,然后写入[代码清单 7.29](#listing-production-webserver-config) 中的内容。这段代码直接摘自 [Heroku 的文档](https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server),[[13](#fn-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](#listing-procfile) 所示。`Procfile` 文件和 `Gemfile` 文件一样,应该放在应用的根目录中。
##### 代码清单 7.30:创建 Puma 需要的 `Procfile` 文件
./Procfile
```
web: bundle exec puma -C config/puma.rb
```
生产环境的 Web 服务器配置好之后,我们可以提交并部署了:[[14](#fn-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](#fig-signup-in-production)。注意图中的地址栏,使用的是 `https://`,而且还有一个锁状图标——表明启用了 SSL。
![signup in production 3rd edition](https://box.kancloud.cn/2016-05-11_5733304c83abb.png)图 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](#fn-15)]所以现在你应该忽略这个提醒。为了让演示应用和系统中的 Ruby 版本保持最新,会遇到很多问题,而且不同的版本之间没有太大的差异。不过要记住,如果想在 Heroku 中运行重要的应用,建议在 `Gemfile` 中明确指定 Ruby 版本号,尽量减少开发环境和生产环境之间的差异。
- Ruby on Rails 教程
- 致中国读者
- 序
- 致谢
- 作者译者简介
- 版权和代码授权协议
- 第 1 章 从零开始,完成一次部署
- 1.1 简介
- 1.2 搭建环境
- 1.3 第一个应用
- 1.4 使用 Git 做版本控制
- 1.5 部署
- 1.6 小结
- 1.7 练习
- 第 2 章 玩具应用
- 2.1 规划应用
- 2.2 用户资源
- 2.3 微博资源
- 2.4 小结
- 2.5 练习
- 第 3 章 基本静态的页面
- 3.1 创建演示应用
- 3.2 静态页面
- 3.3 开始测试
- 3.4 有点动态内容的页面
- 3.5 小结
- 3.6 练习
- 3.7 高级测试技术
- 第 4 章 Rails 背后的 Ruby
- 4.1 导言
- 4.2 字符串和方法
- 4.3 其他数据类型
- 4.4 Ruby 类
- 4.5 小结
- 4.6 练习
- 第 5 章 完善布局
- 5.1 添加一些结构
- 5.2 Sass 和 Asset Pipeline
- 5.3 布局中的链接
- 5.4 用户注册:第一步
- 5.5 小结
- 5.6 练习
- 第 6 章 用户模型
- 6.1 用户模型
- 6.2 用户数据验证
- 6.3 添加安全密码
- 6.4 小结
- 6.5 练习
- 第 7 章 注册
- 7.1 显示用户的信息
- 7.2 注册表单
- 7.3 注册失败
- 7.4 注册成功
- 7.5 专业部署方案
- 7.6 小结
- 7.7 练习
- 第 8 章 登录和退出
- 8.1 会话
- 8.2 登录
- 8.3 退出
- 8.4 记住我
- 8.5 小结
- 8.6 练习
- 第 9 章 更新,显示和删除用户
- 9.1 更新用户
- 9.2 权限系统
- 9.3 列出所有用户
- 9.4 删除用户
- 9.5 小结
- 9.6 练习
- 第 10 章 账户激活和密码重设
- 10.1 账户激活
- 10.2 密码重设
- 10.3 在生产环境中发送邮件
- 10.4 小结
- 10.5 练习
- 10.6 证明超时失效的比较算式
- 第 11 章 用户的微博
- 11.1 微博模型
- 11.2 显示微博
- 11.3 微博相关的操作
- 11.4 微博中的图片
- 11.5 小结
- 11.6 练习
- 第 12 章 关注用户
- 12.1 “关系”模型
- 12.2 关注用户的网页界面
- 12.3 动态流
- 12.4 小结
- 12.5 练习