如何在AWS EC2实例的Rails应用中连接非AWS SFTP服务器?
问题排查与解决方案
针对本地SFTP操作正常、EC2部署后报错Net::SFTP::StatusException opendir /import/ (2, "no such file")的问题,可按以下方向排查:
1. 验证SFTP用户的实际根目录
很多SFTP服务器会给用户配置Chroot Jail,导致不同环境下用户登录后的根路径不一致:
- 在EC2命令行登录SFTP后,执行
pwd查看当前工作目录 - 如果输出不是
/,说明代码里的绝对路径/import/无效,需改为相对路径(如import/)或对应该用户根目录的绝对路径(比如用户根目录是/home/sftp_user,则目标路径应为/home/sftp_user/import/)
2. 检查Sidekiq的环境配置
确认EC2上Sidekiq加载的SFTP参数与本地一致:
- 在Worker中添加日志,输出当前使用的SFTP连接参数及登录后的工作目录:
Net::SFTP.start(sftp_host, sftp_user, :password => sftp_pass) do |sftp| Rails.logger.info "SFTP Host: #{sftp_host}, User: #{sftp_user}" Rails.logger.info "SFTP Current Directory: #{sftp.pwd}" sftp.download!("/import/", "storage/", :recursive => true) end - 查看Sidekiq日志,确认参数是否正确,以及登录后的目录是否与命令行一致
3. 检查Sidekiq运行用户的权限
EC2上Sidekiq的运行用户可能与你SSH登录的用户不同,导致SFTP权限差异:
- 执行
ps aux | grep sidekiq查看Sidekiq的运行用户(如www-data) - 切换到该用户,尝试手动连接SFTP并访问
/import/目录:sudo su - <sidekiq运行用户> sftp <sftp_user>@<sftp_host> # 输入密码后执行 ls /import/ - 如果切换用户后无法访问目录,需调整SFTP服务器对该用户的权限配置
4. 核对Net::SFTP版本与路径格式
- 本地与EC2上的net-sftp版本可能存在差异,分别执行
bundle show net-sftp确认版本一致 - 尝试修改路径格式:去掉末尾斜杠(将
/import/改为/import),或使用相对路径测试
5. 排除SFTP连接的隐式配置差异
命令行SFTP可能读取了~/.ssh/config中的配置(如端口、代理),但Net::SFTP不会自动读取这些:
- 确认EC2上代码中的
sftp_host是否包含正确端口(如sftp.example.com:2222) - 如果SFTP服务器需要特定的SSH选项,可在
Net::SFTP.start中显式传入,比如:Net::SFTP.start(sftp_host, sftp_user, :password => sftp_pass, :port => 2222) do |sftp| # ... end
内容的提问来源于stack exchange,提问作者MelH
相关产品推荐
相关产品推荐

