冷启动
此时,我们应该在所有打算部署的服务器上都有一个部署用户,该用户应该有权写入我们计划部署到的任何位置,默认情况下,这将类似于 /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
。 - Capistrano 识别到为了完成这个请求,它必须先执行任务
git:wrapper
,这是一个先决条件。 - Capistrano 执行了
git:wrapper
任务,上传了/tmp/git-ssh.sh
文件,并将其设置为可执行文件。这个脚本实际上是作为模板处理的。 - 有了 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.
注意:如果你遇到类似 scp: /tmp/git-ssh.sh: Permission denied
的错误,你可能需要设置 :tmp_dir
参数。