Capistrano部署Puma启动失败:shared_path变量未定义问题
兄弟,这个坑我之前踩过!问题出在你手动写的shared/puma.rb直接用了Capistrano的变量,但Puma本身根本不知道这些变量是什么——这些变量是Capistrano部署上下文里的东西,得通过puma-capistrano gem把它们传递过去才行。下面一步步给你解决:
1. 先确认依赖装对了
首先检查你的Gemfile里有没有puma-capistrano这个gem,它是连接Capistrano和Puma的关键:
# Gemfile gem 'puma', group: :production gem 'puma-capistrano', group: :production
跑个bundle install,然后确保部署时服务器上也能拿到这些依赖(可以用cap production deploy:check验证一下)。
2. 在Capfile里加载Puma的Capistrano任务
打开你的Capfile,加上这几行,让Capistrano知道要处理Puma的部署:
# Capfile require 'capistrano/puma' # 如果还要生成Nginx配置配合Puma,再加下面这行(可选) # require 'capistrano/puma/nginx'
3. 别手动写Puma配置!让Capistrano帮你生成
你之前手动创建的shared/puma.rb没用,因为它没经过Capistrano的变量渲染。直接跑这个命令让Capistrano生成正确的配置文件:
cap production puma:config
这个命令会在服务器的shared/config目录下生成puma.rb(注意路径是shared/config/,不是你之前的shared/根目录),而且这个文件是ERB模板,部署时Capistrano会自动把#{shared_path}、#{release_path}替换成服务器上的实际路径。
4. (可选)指定Puma配置路径
如果你的Puma配置不是默认的shared/config/puma.rb,可以在deploy.rb里手动指定:
# deploy.rb set :puma_config, -> { File.join(shared_path, 'config', 'puma.rb') }
5. 重新部署试试
现在跑cap production deploy,然后再启动Puma:
cap production puma:start
为啥之前会报错?
简单说:你写的shared/puma.rb是纯Ruby文件,Puma加载它的时候,上下文里根本没有shared_path这个变量——这个变量只有Capistrano在执行部署任务的时候才存在。而puma-capistrano生成的配置是ERB模板,Capistrano会先把模板里的变量替换成真实路径,再交给Puma加载,这样就不会报错了。
内容的提问来源于stack exchange,提问作者Hipjea

