Gitpod环境下Capistrano部署AWS EC2遇SSH连接超时问题
Gitpod环境下Capistrano部署AWS EC2超时问题排查与解决
问题背景
本地机器执行bundle exec cap production deploy可正常部署Ruby on Rails应用到AWS EC2实例,但在Gitpod环境中执行相同命令时,出现SSH连接超时错误,无法完成部署。
错误信息
Caused by: Errno::ETIMEDOUT: Connection timed out - connect(2) for 3.218.XXX.XXX:22 /home/gitpod/.rvm/rubies/ruby-2.7.3/lib/ruby/2.7.0/socket.rb:64:in `connect' /home/gitpod/.rvm/rubies/ruby-2.7.3/lib/ruby/2.7.0/socket.rb:64:in `connect_internal' /home/gitpod/.rvm/rubies/ruby-2.7.3/lib/ruby/2.7.0/socket.rb:137:in `connect' /home/gitpod/.rvm/rubies/ruby-2.7.3/lib/ruby/2.7.0/socket.rb:642:in `block in tcp' /home/gitpod/.rvm/rubies/ruby-2.7.3/lib/ruby/2.7.0/socket.rb:227:in `each' /home/gitpod/.rvm/rubies/ruby-2.7.3/lib/ruby/2.7.0/socket.rb:227:in `foreach' /home/gitpod/.rvm/rubies/ruby-2.7.3/lib/ruby/2.7.0/socket.rb:632:in `tcp' /workspace/tourme_mvp/vendor/bundle/ruby/2.7.0/gems/net-ssh-7.2.0/lib/net/ssh/transport/session.rb:72:in `initialize' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/net-ssh-7.2.0/lib/net/ssh.rb:256:in `new' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/net-ssh-7.2.0/lib/net/ssh.rb:256:in `start' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/backends/connection_pool.rb:63:in `call' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/backends/connection_pool.rb:63:in `with' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/backends/netssh.rb:177:in `with_ssh' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/backends/netssh.rb:130:in `execute_command' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/backends/abstract.rb:148:in `block in create_command_and_execute' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/backends/abstract.rb:148:in `tap' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/backends/abstract.rb:148:in `create_command_and_execute' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/backends/abstract.rb:61:in `test' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/capistrano-rbenv-2.2.0/lib/capistrano/tasks/rbenv.rake:10:in `block (3 levels) in <top (required)>' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/backends/abstract.rb:31:in `instance_exec' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/backends/abstract.rb:31:in `run' /workspace/app_name/vendor/bundle/ruby/2.7.0/gems/sshkit-1.21.5/lib/sshkit/runners/parallel.rb:12:in `block (2 levels) in execute' Tasks: TOP => rbenv:validate
当前环境配置
- Capistrano 3.17.3、sshkit 1.21.5、Ruby 2.7.3、Rails 6.0.6
- 本地用rbenv,Gitpod用RVM(已排除此为核心问题)
config/deploy.rb配置:
require 'capistrano-db-tasks' set :application, 'app_name' set :repo_url, 'repo_url' set :deploy_to, '/home/deploy/app_name' set :branch, ENV['BRANCH'] if ENV['BRANCH'] set :linked_files, %w{config/database.yml config/master.key} set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system} set :keep_releases, 3 set :keep_assets, 3 set :db_local_clean, true set :db_remote_clean, true namespace :deploy do desc 'Restart application' task :restart do on roles(:app), in: :sequence, wait: 5 do execute :touch, release_path.join('tmp/restart.txt') end end after :publishing, 'deploy:restart' after :finishing, 'deploy:cleanup' end
config/deploy/production.rb配置:
server '3.218.XXX.XXX', user: 'deploy', roles: %w{web app db} server '34.238.XXX.XXX', user: 'deploy', roles: %w{web app db} set :rails_env, 'production'
核心排查方向与解决方案
1. AWS安全组限制(最可能原因)
本地机器能连接EC2,说明安全组已允许本地IP访问22端口,但Gitpod的出口IP不在允许列表内:
- 临时解决:在Gitpod终端执行
curl ifconfig.me获取当前实例公网IP,在AWS控制台的EC2安全组中添加规则,允许该IP访问22端口(TCP)。 - 长期解决:查询Gitpod官方公布的出口IP段,将这些段添加到安全组的22端口允许列表中;或使用AWS Session Manager替代直接SSH连接(无需开放22端口)。
2. Gitpod环境SSH密钥配置
确保Gitpod中拥有EC2实例的访问密钥,且配置正确:
- 将EC2的PEM密钥文件上传到Gitpod的
~/.ssh/目录,设置权限为chmod 600 ~/.ssh/your-key.pem。 - 在
config/deploy.rb中指定密钥路径:
set :ssh_options, { keys: [File.expand_path('~/.ssh/your-key.pem')], auth_methods: ['publickey'] }
- 验证:在Gitpod终端执行
ssh -i ~/.ssh/your-key.pem deploy@3.218.XXX.XXX,确认能正常登录EC2实例。
3. Capistrano SSH代理转发(可选)
如果本地使用SSH代理转发,可在Gitpod中启用:
- 在
config/deploy.rb添加:
set :ssh_options, { forward_agent: true }
- 在Gitpod的SSH配置中启用代理转发(需确保本地密钥已添加到代理,且Gitpod能访问代理)。
4. 使用AWS Session Manager替代直接SSH
无需开放22端口,通过AWS API连接EC2:
- 安装AWS CLI并配置凭证到Gitpod环境。
- 配置Capistrano使用SSM连接,可参考相关插件或自定义SSH命令。
结论
Gitpod环境下Capistrano部署EC2完全可行,核心问题是SSH连接的网络或权限配置缺失。优先排查AWS安全组和Gitpod的SSH密钥配置,这两个是最常见的导致超时的原因。
内容的提问来源于stack exchange,提问作者Benjamin Kim
相关产品推荐
相关产品推荐

