Capistrano logo

At Kisko some of our projects have production environments with IP restrictions, meaning that we can access the servers from our office but not from any random IP address.

Despite this, it is handy and perhaps even necessary that we can deploy and access the servers when working remotely or if an emergency crops up when we’re away from the office. Using a VPN or SOCKS proxy is one option, but luckily it is also pretty easy to configure Capistrano 3 to deploy via a bastion or gateway host.

Set-up Capistrano as your normally would, then add this to your deploy.rb:

if ENV['VIA_BASTION']
  require 'net/ssh/proxy/command'

  # Use a default host for the bastion, but allow it to be overridden
  bastion_host = ENV['BASTION_HOST'] || 'bastion.example.com'

  # Use the local username by default
  bastion_user = ENV['BASTION_USER'] || ENV['USER']

  # Configure Capistrano to use the bastion host as a proxy
  ssh_command = "ssh #{bastion_user}@#{bastion_host} -W %h:%p"
  set :ssh_options, proxy: Net::SSH::Proxy::Command.new(ssh_command)
end

Note: Remember to replace the bastion hostname with your own…

Now when your not deploying from your regular IP address, you can simply set the VIA_BASTION environment variable to deploy via the bastion host. For example:

VIA_BASTION=1 cap production deploy

And that’s it!