准备您的应用程序

这将重点介绍准备 Rails 应用程序,但这里表达的大多数想法在 Python 或 PHP 应用程序中都有类似之处

1. 将您的应用程序提交到某个外部可用的源代码控制托管提供商。

如果您还没有这样做,您应该将您的代码托管在某个提供商处,例如 GitHub、BitBucket、Codeplane 或 repositoryhosting.com。

Capistrano 目前开箱即用地支持 Git、Mercurial 和 SVN。可能存在添加对各种其他系统的支持的第三方插件。

2. 将机密信息移出存储库。

如果您不小心将国家机密提交到存储库,您可能需要采取特殊步骤来永久地从存储库历史记录中删除它们。

理想情况下,应该将 config/database.yml 重命名为类似 config/database.yml.example 的文件。你和你的团队应该在 Capistrano 下,将示例文件复制到各自的开发机器上。这样,database.yml 文件名将被保留,以便我们可以在部署时将生产数据库配置符号链接到该位置。

原始的 database.yml 应该被添加到 .gitignore 中(或者你所使用的版本控制系统的忽略文件概念)。

$ cp config/database.yml{,.example}
$ echo config/database.yml >> .gitignore

对于任何其他秘密文件,都应该这样做。我们将在部署时创建文件的生产版本,并将其符号链接到相应位置。

3. 在你的应用程序中初始化 Capistrano。

$ cd my-project
$ cap install

这将创建一些文件,其中重要的文件包括:

├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
    └── capistrano
            └── tasks

你的新 Capfile 将自动包含 lib/capistrano/tasks 中任何 *.rake 文件中的所有任务。

4. 在生成的配置文件中配置你的服务器地址。

我们这里只处理 staging 环境,所以你可以假装 config/deploy/production.rb 不存在,这在很大程度上是你的事。

Capistrano 将常见的任务分解为一个称为“角色”的概念。也就是说,对于一个典型的 Rails 应用程序,我们大致有三个角色:webappdb

这三个角色可能会让人困惑,因为 web 和 app 服务器的边界有点模糊,例如,如果使用 Passenger 与 Apache,实际上会将你的 app 服务器嵌入到 web 服务器中(将 Passenger 嵌入到 Apache 进程本身)。令人困惑的是,Passenger 也可以在不满足此条件的情况下使用,所以我们暂时忽略这一点。如果你知道其中的区别(例如,你使用 nginx 作为你的 web 服务器,而 puma/unicorn 或类似的作为你的 app 服务器,那应该没问题),那么我们可以假设它们是相同的,这很常见。

生成的示例文件将类似于以下内容:

set :stage, :staging

# Simple Role Syntax
# ==================
# Supports bulk-adding hosts to roles, the primary
# server in each group is considered to be the first
# unless any hosts have the primary property set.
role :app, %w{example.com}
role :web, %w{example.com}
role :db,  %w{example.com}

# Extended Server Syntax
# ======================
# This can be used to drop a more detailed server
# definition into the server list. The second argument
# is something that quacks like a hash and can be used
# to set extended properties on the server.
server 'example.com', roles: %w{web app}, my_property: :my_value

# set :rails_env, :staging

服务器可以通过两种方式定义:使用简单的 role 语法隐式定义,以及使用扩展的 server 语法显式定义。两种方式都会为每个角色定义一个或多个服务器。 appdb 角色只是占位符,如果你使用的是 capistrano/rails-* 附加组件(稍后会详细介绍),那么它们将具有特定的含义。但是,如果你部署的是更简单的应用程序,如果它们对你没有意义,可以随意删除它们。

两种类型都可以指定与服务器或角色关联的可选属性。这些属性包括 Capistrano 要求的属性,例如 SSH 选项(用户名、端口、密钥等),以及任意自定义属性。它们的存在是为了方便用户从类似EC2命令行工具等地方更全面地构建服务器列表,并希望使用扩展属性来完成其环境中合理的操作。

以下展示了定义两个服务器:一个设置了用户名,另一个设置了端口。这些主机字符串会被解析并扩展成与注释后的服务器行等效的内容。

# using simple syntax
role :web, %w{hello@world.com example.com:1234}

# using extended syntax (which is equivalent)
server 'world.com', roles: [:web], user: 'hello'
server 'example.com', roles: [:web], port: 1234

您可以使用两种语法定义服务器或角色,属性将被合并。有关详细信息,请参阅属性文档。

如果您使用简单或扩展语法定义服务器,并显式指定用户或端口号,则最后一个定义将生效。这与标量自定义属性的行为相同。在旧版本的 Capistrano 中,会创建多个服务器,并且合并方式定义不明确。

5. 在 deploy.rb 中设置共享信息。

deploy.rb 是一个可以指定每个环境的通用配置的地方,通常会在这里指定仓库 URL部署用户

生成的示例文件以以下内容开头,后面是一些自文档的、注释掉的配置选项,您可以随意尝试一下。

  set :application, 'my_app_name'
  set :repo_url, 'git@example.com:me/my_repo.git'
  ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }

在这里,我们将设置应用程序的名称,理想情况下,这个名称应该对目标操作系统的文件名安全。

其次,我们设置仓库 URL,这个 URL 必须是部署目标服务器可以访问的地址。

以下是一个典型的示例:请注意,我们将在下一章介绍身份验证,但现在我们假设这个仓库是开源的,并从 Rails 示例和教程 网站获取一个示例应用程序。在那里,我们会找到一些维护良好的典型 Rails 应用程序,以及典型的依赖项。

他们托管的 Rails 应用程序使用 Devise(用于身份验证)和 Cancan(用于授权),以及 Twitter Bootstrap 用于资产,该应用程序已分叉到 Capistrano 仓库,但您可以在这里找到原始的(未修改的)版本 here.

  set :application, 'rails3-bootstrap-devise-cancan-demo'
  set :repo_url, 'https://github.com/capistrano/rails3-bootstrap-devise-cancan'
  set :branch, 'master'

我已经将 :branch 变量简化为一个简单的 set 变量,而不是一个问题提示,因为这个仓库只有一个 master 分支。

总结

此时,Capistrano 已经知道在哪里找到我们的服务器,以及在哪里找到我们的代码。

我们还没有介绍如何授权我们的服务器检出我们的代码(使用 Git 有三种非常好的方法),也没有确定如何授权 Capistrano 在我们的服务器上运行。

Fork me on GitHub