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, as configured by default, won't work, as production can't talk to repo.
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?
Edit:
I've tried this:
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"
But I keep getting this error:
failed: "sh -c 'Creating SSH tunnel...'" on deploy.com
Using Capistrano 3.x, the following works for me:
Please note that
ssh.forward.remote
expects parameters in a different order thanssh -R
, the above is equivalent tossh -R 9000:192.168.1.123:22
This task calls a private method, if anyone knows an official way to get the access Capistrano's ssh connection, please comment or edit.
Edit: Also see the section Tunneling and other related SSH themes of SSHKit's README
Here's are 2 ways to accomplish it.
1st way
not sure if you've seen this thread?
It makes use of the
net-ssh-gateway
library, but creates copies of the local forwarding methods but they're geared for remote access.2nd way
Outlined in an answer to this SO question:
This technique is very similar to the 1st way. First you need to create 2 paths to the repository:
Then before you deploy you'll need to setup the remote forward:
Followed by your deploy:
See this answer to that SO question for more details: