冷启动

此时,我们应该在所有打算部署的服务器上都有一个部署用户,该用户应该有权写入我们计划部署到的任何位置,默认情况下,这将类似于 /var/www/my-application

我们已经设置了具有适当权限的目录,以便我们可以部署而不会破坏任何东西,并且我们团队中的每个人都可以部署。

让我们回顾一下到目前为止我们所做的事情,以及如何检查一切是否正常,在本指南的最后一步中,我们将创建仅生产环境的共享文件。

同样,本指南假设使用 Ruby on Rails,但到目前为止我们所做的大多数事情都适用于其他框架和技术,只是略有修改。

1. 检查远程机器上的目录结构

me@localhost $ ssh deploy@remote 'ls -lR /var/www/my-application'
my-application:
total 8
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 releases
drwxrwsr-x 2 deploy deploy 4096 Jun 24 20:55 shared

my-application/releases:
total 0

my-application/shared:
total 0

这将通过一个简单的命令检查您设置的 SSH 密钥是否正常工作(您可能需要输入密码),以及目录的权限是否可见。

2. 编写第一个cap 任务将此形式化为检查!

现在我们已经知道如何检查权限和仓库访问权限,我们将快速介绍一个简单的 Cap 任务,以便在所有机器上检查这些内容。

desc "Check that we can access everything"
task :check_write_permissions do
  on roles(:all) do |host|
    if test("[ -w #{fetch(:deploy_to)} ]")
      info "#{fetch(:deploy_to)} is writable on #{host}"
    else
      error "#{fetch(:deploy_to)} is not writable on #{host}"
    end
  end
end

运行此命令应该会提供一个相当不错的概述,每台服务器一行输出。这也是您首次接触 Capistrano API 以编写自己的任务,即 desc()task()on()roles()test()info()error()

前两种方法,desc()task() 实际上来自 Rake,Rake 是 Capistrano 任务系统的基础库,其他方法是我们子项目 SSHKit 的一部分。我们将在稍后深入探讨这些内容,但将这些行添加到 ./lib/capistrano/tasks 中的一个文件中,将其命名为类似 access_check.rake 的名称,然后从顶层目录运行 cap -T,我们就可以看到列出的任务。

me@localhost $ bundle exec cap -T
# ... lots of other tasks ...
cap check_write_permissions  # Check that we can access everything
# ... lots of other tasks ...

然后我们只需调用它。

me@localhost $ bundle exec cap staging check_write_permissions
DEBUG [82c92144] Running /usr/bin/env [ -w /var/www/my-application ] on myserver.com
DEBUG [82c92144] Command: [ -w /var/www/my-application ]
DEBUG [82c92144] Finished in 0.456 seconds command successful.
INFO /var/www/my-application is writable on myserver.com

如果我们做错了什么,这将不会发生,我们将知道我们需要加入邮件列表寻求帮助,进入 IRC 或询问朋友。

根据您设置 Git 身份验证凭据的方式,检查 Git 可能有点复杂,因此我们在核心库中提供了一个任务,可以检查您的 Git 访问权限,Git 并不是特别可脚本化,因此必须将 Git 包裹在一个 shell 脚本中,使其能够正常工作。

Capistrano 恰好做到了这一点,因此要检查 Git 访问权限是否正常工作,我们只需调用。

me@localhost $ cap staging git:check

此任务在默认的 Git SCM 策略中定义,看起来很像我们上面编写的检查文件权限的代码,但是 Git 检查配方要复杂一些,需要处理三种不同的身份验证方案,这些方案需要以不同的方式解决。此任务表示对 git:git-wrapper 任务的依赖,该任务首先由 Capistrano 为我们解决。(这是我们从 Rake 继承的部分内容之一)。

如果失败,我们将看到。

me@localhost $ cap staging git:check
cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
 INFO Uploading /tmp/git-ssh.sh 100%
 INFO [118bd3e4] Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
DEBUG [118bd3e4] Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
 INFO [118bd3e4] Finished in 0.049 seconds command successful.
 INFO [a996463f] Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on harrow
DEBUG [a996463f] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git )
DEBUG [a996463f]  Warning: Permanently added 'github.com,204.232.175.90' (RSA) to the list of known hosts.
DEBUG [a996463f]  Permission denied (publickey).
DEBUG [a996463f]  fatal: The remote end hung up unexpectedly
cap aborted!
git stdout: Nothing written
git stderr: Nothing written

Tasks: TOP => git:check
(See full trace by running task with --trace)

这通常会根据您的终端颜色支持显示得更漂亮,您可能会看到类似这样的内容。

Capistrano Git Check Colour Example

简而言之,我们做了什么

  1. 我们要求 Capistrano 运行命令 git:check
  2. Capistrano 识别到为了完成这个请求,它必须先执行任务 git:wrapper,这是一个先决条件
  3. Capistrano 执行了 git:wrapper 任务,上传了 /tmp/git-ssh.sh 文件,并将其设置为可执行文件。这个脚本实际上是作为模板处理的。
  4. 有了 git wrapper,我们可以安全地对 Git 进行脚本操作,而不会提示我们输入,因此我们要求 git 对我们定义的仓库进行 ls-remote 操作。由于这以一个 不干净的状态 退出,Capistrano 中止并打印出错误消息,以便我们尝试找出问题所在。

在这种情况下,我们将使用 SSH 代理转发,我们可以通过编写一个小型 Cap 任务或简单地使用 SSH 为我们完成来检查它是否正常工作,选择权在你。

# lib/capistrano/tasks/agent_forwarding.rake
desc "Check if agent forwarding is working"
task :forwarding do
  on roles(:all) do |h|
    if test("env | grep SSH_AUTH_SOCK")
      info "Agent forwarding is up to #{h}"
    else
      error "Agent forwarding is NOT up to #{h}"
    end
  end
end

这产生了以下输出

cap staging forwarding
DEBUG [f1269276] Running /usr/bin/env env | grep SSH_AUTH_SOCK on example.com
DEBUG [f1269276] Command: env | grep SSH_AUTH_SOCK
DEBUG [f1269276]  SSH_AUTH_SOCK=/tmp/ssh-nQUEmyQ2nS/agent.2546
DEBUG [f1269276] Finished in 0.453 seconds command successful.
 INFO Agent forwarding is up to example.com

如果你不想编写 Capistrano 任务,可以简单地执行以下操作

me@localhost $ ssh -A example.com 'env | grep SSH_AUTH_SOCK'
SSH_AUTH_SOCK=/tmp/ssh-Tb6X8V53tm/agent.2934

如果我们看到 SSH_AUTH_SOCK 输出,这表明 SSH 代理转发已启用,如果在你的本地机器上 ssh-add -l 显示了 SSH 密钥,那么我们就可以开始了。确保你使用的是 git@... 仓库 URL

cap staging git:check
DEBUG Uploading /tmp/git-ssh.sh 0%
 INFO Uploading /tmp/git-ssh.sh 100%
 INFO [21382716] Running /usr/bin/env chmod +x /tmp/git-ssh.sh on example.com
DEBUG [21382716] Command: /usr/bin/env chmod +x /tmp/git-ssh.sh
 INFO [21382716] Finished in 0.047 seconds command successful.
 INFO [f40edfbb] Running /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git on example.com
DEBUG [f40edfbb] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/git-ssh.sh /usr/bin/env git ls-remote git@github.com:capistrano/rails3-bootstrap-devise-cancan.git )
DEBUG [f40edfbb]  3419812c9f146d9a84b44bcc2c3caef94da54758  HEAD
DEBUG [f40edfbb]  3419812c9f146d9a84b44bcc2c3caef94da54758  refs/heads/master
 INFO [f40edfbb] Finished in 3.319 seconds command successful.

Capistrano Git Check Colour Example

注意:如果你遇到类似 scp: /tmp/git-ssh.sh: Permission denied 的错误,你可能需要设置 :tmp_dir 参数。

Fork me on GitHub