Rails 7部署遇NameError: uninitialized constant Rails问题求助
问题原因
不是Rails7移除了初始化器自动加载功能,核心问题是Capistrano的deploy.rb脚本在执行时,根本没有加载Rails应用环境。不管是Rails6还是Rails7,Capistrano本身的设计就是独立于Rails运行的,你之前在Rails6里能正常运行,大概率是项目里有额外的自定义逻辑意外加载了Rails环境,属于特殊情况,不是标准用法。
解决方案
给你三种可行的解决方式,按推荐程度排序:
方式1:用环境变量(推荐)
把Git仓库地址放到环境变量里,deploy.rb直接读取:
lock "~> 3.17.1" set :application, "my app" set :repo_url, ENV['GIT_REPO_URL'] # 从环境变量取地址 set :deploy_to, "/home/myapp/#{fetch :application}" append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', '.bundle', 'public/system', 'public/uploads' set :keep_releases, 5
部署前在终端导出环境变量:
export GIT_REPO_URL="你的Git仓库地址" bin/bundle exec cap production deploy --trace
也可以把环境变量加到本地的~/.bashrc/~/.zshrc里,避免每次都输入。
方式2:手动加载Rails Credentials(不依赖完整Rails环境)
不需要加载整个Rails,只加载Credentials模块读取配置:
lock "~> 3.17.1" # 先加载Rails Credentials模块 require "rails/credentials" require "pathname" # 定义项目根目录 rails_root = Pathname.new(__dir__).join("..").expand_path # 读取默认的credentials文件 credentials = Rails::Credentials.read(rails_root.join("config/credentials.yml.enc"), rails_root.join("config/master.key")) set :application, "my app" set :repo_url, credentials.dig(:git, :repo_url) # 从credentials取地址 set :deploy_to, "/home/myapp/#{fetch :application}" append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', '.bundle', 'public/system', 'public/uploads' set :keep_releases, 5
如果用的是分环境的credentials(比如config/credentials/production.yml.enc),可以根据Capistrano的stage动态读取:
credentials = Rails::Credentials.read(rails_root.join("config/credentials/#{fetch(:stage)}.yml.enc"), rails_root.join("config/master.key"))
方式3:强制加载完整Rails环境(不推荐)
在deploy.rb开头加载Rails环境,这样就能用Rails.application.credentials了,但这种方式会让部署脚本依赖整个Rails应用的配置,可能引发不必要的问题:
lock "~> 3.17.1" # 加载Rails环境 require File.expand_path('../config/environment', __dir__) set :application, "my app" set :repo_url, Rails.application.credentials.git[:repo_url] set :deploy_to, "/home/myapp/#{fetch :application}" append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', '.bundle', 'public/system', 'public/uploads' set :keep_releases, 5
内容的提问来源于stack exchange,提问作者Ahmed Gasanov
相关产品推荐
相关产品推荐

