问题描述
我们正在使用Capistrano将新版本的PHP应用程序自动推送到生产服务器。生产服务器(我们称为生产服务器)是公共的,而我们的存储库服务器(我们称为存储库)位于公司防火墙以及我们自己的计算机后面。
We're using Capistrano to automate pushing new versions of a PHP application to a production server. The production server (we'll call it production) is public, while our repository server (we'll call it repo) sits behind our corporate firewall, along with our own machines.
默认情况下配置的Capistrano不起作用,因为生产无法与回购交易。
Capistrano, as configured by default, won't work, as production can't talk to repo.
我想知道是否可以将capistrano设置为SSH首先进行回购,然后SSH进行生产以在端口上打开隧道,然后可以使用该隧道从SSH生产回购以从SCM中提取更改。
I was wondering if there was someway I could setup capistrano to SSH to repo first, then SSH to production opening a tunnel on a port that I can then use to SSH from production back to repo to pull the changes from SCM.
我只是不知道该如何设置或找到更好的解决方案。
I just can't figure out how to set this up or figure out a better solution. Ideas?
编辑:
我已经尝试过了:
role :web, "deploy.com"
namespace :deploy do
task :remote_tunnel do
run 'Creating SSH tunnel...' do |channel, stream, data|
ssh = channel.connection
ssh.forward.remote(22, 'server.com', 10000, '127.0.0.1')
ssh.loop {!ssh.forward.active_remotes.include?([10000, '127.0.0.1'])}
end
end
end
before "deploy:update_code", "deploy:remote_tunnel"
但我一直收到此错误:
failed: "sh -c 'Creating SSH tunnel...'" on deploy.com
推荐答案
有两种方法可以实现它。
Here's are 2 ways to accomplish it.
不确定您是否看过此线程?
not sure if you've seen this thread?
- https://groups.google.com/forum/?fromgroups=#!topic/capistrano/RVwMim-qnMg
它利用 net-ssh-gateway
库,但创建本地转发方法的副本,但它们
It makes use of the net-ssh-gateway
library, but creates copies of the local forwarding methods but they're geared for remote access.
class Net::SSH::Gateway
# Opens a SSH tunnel from a port on a remote host to a given host and port
# on the local side
# (equivalent to openssh -R parameter)
def open_remote(port, host, remote_port, remote_host = "127.0.0.1")
ensure_open!
@session_mutex.synchronize do
@session.forward.remote(port, host, remote_port, remote_host)
end
if block_given?
begin
yield [remote_port, remote_host]
ensure
close_remote(remote_port, remote_host)
end
else
return [remote_port, remote_host]
end
rescue Errno::EADDRINUSE
retry
end
# Cancels port-forwarding over an open port that was previously opened via
# open_remote.
def close_remote(port, host = "127.0.0.1")
ensure_open!
@session_mutex.synchronize do
@session.forward.cancel_remote(port, host)
end
end
end
第二种方式
对此问题的答案概述:
2nd way
Outlined in an answer to this SO question:
- Is it possible to do have Capistrano do a checkout over a reverse SSH tunnel?
此技术与第一种方法非常相似。首先,您需要为存储库创建2条路径:
This technique is very similar to the 1st way. First you need to create 2 paths to the repository:
# deploy.rb
set :local_repository, "ssh://git@serverbehindfirewall/path/to/project.git"
set :repository, "ssh://git@localhost:9000/path/to/project.git"
然后,在部署之前,您需要设置远程转发:
Then before you deploy you'll need to setup the remote forward:
% ssh -R 9000:serverbehindfirewall:22 [email protected]
# CTRL + C + A (Screen) or ⌘ + T (Terminal.app) to open new tab
随后是您的部署:
% cap HOSTFILTER=deployserver.com deploy # HOSTFILTER reduces set to specified host. Only useful if you have multiple servers.
有关此问题的更多信息,请参见此答案:
See this answer to that SO question for more details:
- https://stackoverflow.com/a/3953351/33204
这篇关于Capistrano,防火墙和隧道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!