Rails 7应用部署至Fly.io时遭遇ActiveSupport::EncryptedFile::MissingKeyError错误的解决求助
解决Rails 7部署Fly.io时的MissingKeyError问题
我刚帮几个朋友解决过一模一样的问题,核心原因你其实已经猜到了:构建阶段(比如预编译assets)需要访问RAILS_MASTER_KEY,但你之前的配置没让这个密钥在构建过程中持续生效。下面给你几个简单可行的解决方案,都是针对Docker新手友好的:
方案1:直接生成Rails期望的production.key文件(推荐)
Rails默认会优先读取config/credentials/production.key文件,所以我们可以在Docker构建阶段用Fly的build secret把密钥写入这个文件:
步骤1:修改Dockerfile
在预编译assets的步骤之前,添加这段代码(确保你的WORKDIR已经设置为/app):
# 写入production.key并设置正确权限 RUN --mount=type=secret,id=RAILS_MASTER_KEY \ cat /run/secrets/RAILS_MASTER_KEY > config/credentials/production.key && \ chmod 0600 config/credentials/production.key
注意:
chmod 0600是必须的,Rails会拒绝读取权限过于开放的密钥文件。
步骤2:重新部署
还是用你之前的部署命令就行:
fly deploy --build-secret RAILS_MASTER_KEY=your_actual_secret_key_here
方案2:在构建阶段临时设置环境变量
如果不想生成文件,也可以在执行预编译的同一个RUN命令里注入环境变量(因为Docker每个RUN都是独立的shell会话,单独赋值的变量不会传递到下一个RUN):
修改Dockerfile里的预编译步骤:
RUN --mount=type=secret,id=RAILS_MASTER_KEY \ export RAILS_MASTER_KEY=$(cat /run/secrets/RAILS_MASTER_KEY) && \ RAILS_ENV=production bundle exec rails assets:precompile
关键注意点
- Fly控制台设置的环境变量是运行阶段的,构建阶段完全拿不到,这就是你之前设置了环境变量还是报错的原因!
- 确保你的
credentials.yml.enc已经提交到代码仓库了,不然构建阶段找不到加密文件也会报错。 - 检查Dockerfile里的
WORKDIR /app是否正确,如果你的应用在容器里的路径不是/app,要对应修改文件路径。
完整Dockerfile示例片段
给你一个简化版的完整Dockerfile参考,确保所有步骤衔接正确:
FROM ruby:3.2.2-slim # 设置工作目录 WORKDIR /app # 安装系统依赖(按需调整) RUN apt-get update && apt-get install -y build-essential libpq-dev nodejs # 安装Ruby依赖 COPY Gemfile Gemfile.lock ./ RUN bundle install --without development test # 复制应用代码 COPY . . # 写入production.key(核心步骤) RUN --mount=type=secret,id=RAILS_MASTER_KEY \ cat /run/secrets/RAILS_MASTER_KEY > config/credentials/production.key && \ chmod 0600 config/credentials/production.key # 预编译静态资源 RUN RAILS_ENV=production bundle exec rails assets:precompile # 清理临时文件 RUN rm -rf tmp/cache # 启动应用 CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
内容的提问来源于stack exchange,提问作者Arel
相关产品推荐
相关产品推荐

