如何在生产服务器设置RAILS_MASTER_KEY?Capistrano部署Rails 6遇阻
Let's break down why you're hitting this MissingKeyError and fix it step by step—this is a common gotcha with Rails 6's environment-specific credentials system.
First, Understand the Core Issue
Rails 6 changed how credentials work by introducing environment-specific credentials. When you run rails credentials:edit --environment production, it generates two files:
config/credentials/production.yml.enc(your encrypted production secrets)config/credentials/production.key(the key to decrypt those secrets)
Your error message clearly states it's looking for /.../config/credentials/production.key, but you were uploading and linking config/master.key—that's the key for the default/development environment, not production. That's the main reason the deploy failed.
Step 1: Fix Your Capistrano Linked Files Configuration
You have conflicting linked_files settings (both append and set), and you're linking the wrong file. Replace those lines with:
# config/deploy.rb # Append the production key to the default linked files list (don't overwrite with `set`) append :linked_files, "config/credentials/production.key"
Using append ensures you don't lose other default linked files (like database.yml) that Capistrano relies on.
Step 2: Update Your Key Upload Task
Your current task uploads master.key to the wrong path. We need to:
- Create the
credentialssubdirectory inshared/config(Capistrano won't auto-create subfolders) - Upload the correct
production.key - Set strict file permissions (keys need
600to be secure and recognized by Rails)
Replace your existing deploy:check:set_master_key task with this:
namespace :deploy do namespace :check do before :linked_files, :set_production_key do on roles(:app), in: :sequence, wait: 5 do # Create the credentials directory if it doesn't exist unless test("[ -d #{shared_path}/config/credentials ]") execute :mkdir, "-p #{shared_path}/config/credentials" end # Upload local production.key to the server's shared directory (if missing) unless test("[ -f #{shared_path}/config/credentials/production.key ]") upload! 'config/credentials/production.key', "#{shared_path}/config/credentials/production.key" # Lock down permissions—critical for security execute :chmod, "600 #{shared_path}/config/credentials/production.key" end end end end end
Step 3: Clean Up Old (Incorrect) Files (Optional)
If you previously uploaded the wrong master.key to the server, clean it up to avoid confusion:
# Run this on your production server rm /home/deploy/tribe/shared/config/master.key
Step 4: Re-Deploy
Now run your Capistrano deploy command again:
cap production deploy
Capistrano will now link the correct production.key from shared/config/credentials to your release directory, and Rails will find the key it needs to decrypt your production credentials.
Alternative: Use the RAILS_MASTER_KEY Environment Variable
If you prefer not to upload the key file, you can set the RAILS_MASTER_KEY directly in your server's environment:
- Edit your Nginx/Passenger site config (e.g.,
/etc/nginx/sites-available/your_app) - Add this line inside your
serverblock:passenger_env_var RAILS_MASTER_KEY "your-production-key-here"; - Restart Nginx:
sudo systemctl restart nginx
This tells Passenger to inject the key as an environment variable, so Rails will pick it up without needing the physical key file.
内容的提问来源于stack exchange,提问作者Thierry

