Capistrano部署在git:check阶段失败 - 权限被拒绝(publickey)

7 浏览
0 Comments

Capistrano部署在git:check阶段失败 - 权限被拒绝(publickey)

本地操作系统:Windows 10 Pro(使用Git Bash作为终端)

暂存服务器操作系统:Ubuntu 16.04 LTS

我一直在努力在暂存服务器上实现基本的Capistrano部署。我按照此指南设置了Capistrano。

部署过程总是在git:check阶段失败,据称没有权限访问我在GitLab上的仓库。我确定我的SSH代理转发正常工作,因为我能够使用我的SSH密钥SSH登录服务器并访问GitLab。SSH密钥没有存储在我的服务器上:

$ ssh deploy@myserver.com
deploy@MyServer:~$ ssh -T git@gitlab.com
debug1: client_input_channel_open: ctype auth-agent@openssh.com rchan 2 win 65536 max 16384
debug1: channel 1: new [authentication agent connection]
debug1: confirm auth-agent@openssh.com
Welcome to GitLab, Alexander!debug1: channel 1: FORCE input drain

到目前为止,关于这个问题的所有问题都没有起作用。

以下是我的部署文件:

deploy.rb

set :application, "myapp"

set :branch, "master"

set :repo_url, "git@gitlab.com:MyApp/myapp.git"

# Defaults to false

# Skip migration if files in db/migrate were not modified

set :conditionally_migrate, true

set :ssh_options, { forward_agent: true }

set :rvm_ruby_version, '2.2.6'

# Default deploy_to directory is /var/www/my_app_name

set :deploy_to, "/var/www/#{fetch(:application)}/"

set :deploy_user, "deploy"

# Tells Capistrano to store config/database.yml file inside a directory called /shared, which is meant for any files

# we want to persist between deploys

set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')

# Directories that are meant to persist between deploys, and they will also be stored inside /shared

set :linked_dirs, fetch(:linked_dirs, []).push('bin', 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')

# The specs that should be run before deployment is allowed to continue

set :tests, []

# Delayed Job Config: https://github.com/AgileConsultingLLC/capistrano3-delayed-job

set :delayed_job_workers, 3

# Keep the last 5 deploys for rollback purposes

set :keep_releases, 5

namespace :deploy do

after :restart, :clear_cache do

on roles(:web), in: :groups, limit: 3, wait: 10 do

# Here we can do anything such as:

# within release_path do

# execute :rake, 'cache:clear'

# end

end

end

end

staging.rb

set :stage, :staging

set :rails_env, :staging

role :app, %w{deploy@myserver.com}

role :web, %w{deploy@myserver.com}

role :db, %w{deploy@myserver.com}

以下是我部署时的Capistrano调试日志:

$ bundle exec cap staging deploy --trace
** Invoke staging (first_time)
** Execute staging
** Invoke load:defaults (first_time)
** Execute load:defaults
** Invoke rvm:hook (first_time)
** Invoke passenger:rvm:hook (first_time)
** Invoke passenger:test_which_passenger (first_time)
** Execute passenger:test_which_passenger
** Execute passenger:rvm:hook
** Execute rvm:hook
** Invoke rvm:check (first_time)
** Execute rvm:check
rvm 1.29.3 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io]
ruby-2.2.6
ruby 2.2.6p396 (2016-11-15 revision 56800) [x86_64-linux]
** Invoke bundler:map_bins (first_time)
** Invoke passenger:bundler:hook (first_time)
** Execute passenger:bundler:hook
** Execute bundler:map_bins
** Invoke deploy:set_rails_env (first_time)
** Execute deploy:set_rails_env
** Invoke deploy:set_linked_dirs (first_time)
** Execute deploy:set_linked_dirs
** Invoke deploy:set_rails_env
** Invoke deploy (first_time)
** Execute deploy
** Invoke deploy:starting (first_time)
** Execute deploy:starting
** Invoke deploy:check (first_time)
** Invoke git:check (first_time)
** Invoke git:wrapper (first_time)
** Execute git:wrapper
00:00 git:wrapper
      01 mkdir -p /tmp
     01 deploy@myserver.com 0.286s
      Uploading /tmp/git-ssh-myapp-staging-localuser.sh 100.0%
      02 chmod 700 /tmp/git-ssh-myapp-staging-localuser.sh
     02 deploy@myserver.com 0.277s
** Execute git:check
00:01 git:check
      01 git ls-remote git@gitlab.com:MyApp/myapp.git HEAD
      01 Permission denied (publickey).
      01 fatal: Could not read from remote repository.
      01
      01 Please make sure you have the correct access rights
      01 and the repository exists.
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as deploy@myserver.com: git exit status: 128
git stdout: Nothing written
git stderr: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/runners/parallel.rb:11:in `block (2 levels) in execute'
Caused by:
SSHKit::Command::Failed: git exit status: 128
git stdout: Nothing written
git stderr: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/command.rb:99:in `exit_status='
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/backends/netssh.rb:169:in `execute_command'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/backends/abstract.rb:141:in `block in create_command_and_execute'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/backends/abstract.rb:141:in `tap'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/backends/abstract.rb:141:in `create_command_and_execute'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/backends/abstract.rb:74:in `execute'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/capistrano-3.10.1/lib/capistrano/scm/git.rb:77:in `git'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/capistrano-3.10.1/lib/capistrano/scm/git.rb:38:in `check_repo_is_reachable'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/capistrano-3.10.1/lib/capistrano/scm/tasks/git.rake:19:in `block (4 levels) in eval_rakefile'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/backends/abstract.rb:93:in `with'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/capistrano-3.10.1/lib/capistrano/scm/tasks/git.rake:18:in `block (3 levels) in eval_rakefile'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/backends/abstract.rb:29:in `instance_exec'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/backends/abstract.rb:29:in `run'
C:/Ruby22/lib/ruby/gems/2.2.0/gems/sshkit-1.15.1/lib/sshkit/runners/parallel.rb:12:in `block (2 levels) in execute'
Tasks: TOP => deploy:check => git:check
The deploy has failed with an error: Exception while executing as deploy@myserver.com: git exit status: 128
git stdout: Nothing written
git stderr: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
** Invoke deploy:failed (first_time)
** Execute deploy:failed
** DEPLOY FAILED
** Refer to log/capistrano.log for details. Here are the last 20 lines:
 DEBUG [6b6ba2d0] Finished in 0.471 seconds with exit status 0 (successful).
 DEBUG [c6e2d7dc] Running ~/.rvm/bin/rvm 2.2.6 do ruby --version as deploy@myserver.com
 DEBUG [c6e2d7dc] Command: ~/.rvm/bin/rvm 2.2.6 do ruby --version
 DEBUG [c6e2d7dc]       ruby 2.2.6p396 (2016-11-15 revision 56800) [x86_64-linux]
 DEBUG [c6e2d7dc] Finished in 0.608 seconds with exit status 0 (successful).
  INFO [fd5500a8] Running /usr/bin/env mkdir -p /tmp as deploy@myserver.com
 DEBUG [fd5500a8] Command: /usr/bin/env mkdir -p /tmp
  INFO [fd5500a8] Finished in 0.286 seconds with exit status 0 (successful).
 DEBUG Uploading /tmp/git-ssh-myapp-staging-localuser.sh 0.0%
  INFO Uploading /tmp/git-ssh-myapp-staging-localuser.sh 100.0%
  INFO [f33d4873] Running /usr/bin/env chmod 700 /tmp/git-ssh-myapp-staging-localuser.sh as deploy@myserver.com
 DEBUG [f33d4873] Command: /usr/bin/env chmod 700 /tmp/git-ssh-myapp-staging-localuser.sh
  INFO [f33d4873] Finished in 0.277 seconds with exit status 0 (successful).
  INFO [86d3cd5a] Running /usr/bin/env git ls-remote git@gitlab.com:MyApp/myapp.git HEAD as deploy@myserver.com
 DEBUG [86d3cd5a] Command: ( export GIT_ASKPASS="/bin/echo" GIT_SSH="/tmp/git-ssh-myapp-staging-localuser.sh" ; /usr/bin/env git ls-remote git@gitlab.com:MyApp/myapp.git HEAD )
 DEBUG [86d3cd5a]       Permission denied (publickey).
 DEBUG [86d3cd5a]       fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.

我尝试手动在本地和远程服务器上运行Capistrano尝试的命令,它们都成功。我真的很困惑,非常感谢任何帮助!

0
0 Comments

Capistrano部署失败的问题出现的原因是Git Bash没有在运行chmod 700 ~/.ssh时将~/.ssh目录的权限更改为0700。这导致在Capistrano部署时SSH代理转发无法正常工作,但在手动SSH登录到服务器时可以正常工作。为了解决这个问题,我决定尝试使用Bash on Ubuntu on Windows(BUW)而不是Git Bash,并且部署成功了!我将相同的配置和密钥从Git Bash复制到了BUW中。唯一的区别是我能够将BUW的~/.ssh目录权限更改为0700。因此,以下是我的问题的解决方法:

1. 创建部署密钥并将其添加到GitLab

正如as、和M所指出的,我需要为GitLab创建一个部署密钥并在服务器上授权它。以下是我完成这个步骤的方法:

  1. 在本地机器上生成一个新的SSH密钥:ssh-keygen -t rsa -b 4096
  2. 复制公钥的输出:cat ~/.ssh/id_rsa.pub
  3. SSH登录到我的服务器
  4. 将公钥添加到~/.ssh/authorized_keys的末尾
  5. 回到本地机器,在浏览器中打开GitLab,进入我的仓库页面,在设置 > 仓库 > 部署密钥中粘贴公钥

2. 使用BUW代替Git Bash

  1. 在本地机器上,我按照这个Stack Overflow答案的指示设置BUW在会话加载时启动SSH代理。
  2. 更改~/.ssh的权限:chmod 700 ~/.ssh
  3. 启动SSH代理并将我的部署密钥添加到其中:

    eval $(ssh-agent -s)
    ssh-add ~/.ssh/id_rsa
    

我从我的deploy.rb文件中删除了set :ssh_options行,因为没有它也可以正常工作。

就是这样!从现在开始,看来我将使用BUW进行部署。

官方文档:capistranorb.com/documentation/getting-started/…

0
0 Comments

根据cap deploy的输出,看起来从你的笔记本电脑到服务器的SSH连接不是问题所在。

这个问题是在capistrano尝试通过SSH运行git ls-remote git.com:MyApp/myapp.git HEAD时出现的。

你需要将公钥添加到GitLab中的SSH Keys,因为SSH代理转发需要在所有目标系统上安装公钥。在你的情况下,GitLab是一个目标系统。

cat ~/.ssh/id_rsa.pub # 复制公钥的内容(文件名可能不同)

登录到GitLab,并将公钥粘贴到你的存储库的SSH Keys中(在存储库设置中找到),然后应该没问题了。

你还需要在ssh_options中指定使用SSH密钥创建的用户。

set :ssh_options, {

forward_agent: true,

user: 'deploy',

}

感谢你的回答。使用SSH代理转发,如果我已经在我的本地环境中使用了密钥,那么一旦我SSH到服务器上,代理不应该对密钥有访问权限吗?我已经将公钥放在服务器上的authorized_keys文件中。

你本地环境和服务器之间的SSH连接不是问题所在。问题在于服务器和GitLab之间的连接。我已经更新了我的答案(请参见EDIT部分)。

当你部署到staging时,你是从哪里运行capistrano的?从你的本地工作站,还是从另一台服务器上运行?

我是从我的本地工作站上运行cap staging deploy的。

如果你以deploy用户身份登录到staging服务器并以deploy用户身份运行git ls-remote git.com:MyApp/myapp.git HEAD,是否成功?

是的,确实成功了。

你的staging服务器上是否正在运行ssh-agent?此外,你是否检查了staging服务器上sshd_config的输出,以确保允许AllowAgentForwarding?

是的,在我通过SSH登录后,它正在我的staging服务器上运行。我在我的sshd_config中设置了AllowAgentForwarding yes。

你是否将公钥添加到Gitlab中?SSH代理转发确实需要在所有目标系统上安装公钥。在这种情况下,Gitlab是一个目标系统。

0
0 Comments

问题原因:在部署过程中出现了“Permission denied (publickey)”错误,原因是缺少公钥或公钥未正确配置。

解决方法:

1. 在本地系统上检查是否存在“~/.ssh/id_rsa.pub”公钥文件,如果不存在,则创建一个新的:

$ ssh-keygen -t rsa

2. 将新创建的公钥“~/.ssh/id_rsa.pub”添加到仓库的部署(访问)密钥中:

- Bitbucket:按照以下链接中的步骤添加公钥:[https://confluence.atlassian.com/bitbucket/set-up-ssh-for-git-728138079.html#SetupSSHforGit-Step4.InstallthepublickeyonyourBitbucketaccount](https://confluence.atlassian.com/bitbucket/set-up-ssh-for-git-728138079.html#SetupSSHforGit-Step4.InstallthepublickeyonyourBitbucketaccount)

- Github:按照以下链接中的步骤添加公钥:[https://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys](https://developer.github.com/v3/guides/managing-deploy-keys/#deploy-keys)

- GitLab:按照以下链接中的步骤添加公钥:[https://docs.gitlab.com/ce/ssh/README.html#deploy-keys](https://docs.gitlab.com/ce/ssh/README.html#deploy-keys)

3. 将公钥加载到ssh-agent中:

- 检查ssh-agent是否正在运行,如果没有,请启动ssh agent:

$ ssh-agent /bin/bash

- 将“id_rsa”密钥添加到ssh agent:

$ ssh-add ~/.ssh/id_rsa

注意:如果在部署过程中出现“Access denied to the repository”错误,则有时需要在每次部署之前执行此步骤。

4. 将本地SSH密钥添加到部署服务器的Authorized Keys文件中(记得将端口号替换为自定义的端口号):

$ cat ~/.ssh/id_rsa.pub | ssh -p port_num user_ip 'cat >> ~/.ssh/authorized_keys'

5. 修改deploy.rb文件中的ssh_options配置:

set :ssh_options, { forward_agent: true, user: "deploy", auth_methods: ['publickey'], keys: %w(~/.ssh/privatekey.pem) }

将“~/.ssh/privatekey.pem”替换为SSH私钥文件的路径。

6. 运行部署命令:

$ cap staging deploy

将“staging”替换为所需的环境。

如果以上步骤仍然无法解决问题,可以尝试按照第二步中的链接中提供的更详细步骤进行操作,并确保正确添加公钥到仓库的部署(访问)密钥中。

0