7.5 专业部署方案
最后更新于:2022-04-01 22:29:23
# 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://docs.gechiui.com/gc-content/uploads/sites/kancloud/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 版本号,尽量减少开发环境和生产环境之间的差异。
';