Kamal v2部署Rails 8应用时Propshaft无法找到application.css
Rails 8.0.0 + Kamal v2 + Propshaft 部署后资产找不到问题的排查与解决
问题背景
使用Kamal v2部署Rails 8.0.0应用,采用Propshaft作为资产管理工具(未使用Node或其他JS工具),SCSS已编译为CSS并推送至容器的app/assets/builds目录,但Rails运行时抛出Propshaft::MissingAssetError,提示找不到application.css。
错误日志
2024-11-17T17:26:45.976357325Z Information for cause: Propshaft::MissingAssetError (The asset 'application.css' was not found in the load path.): 2024-11-17T17:26:45.976363158Z [d1968adc-03c5-4e53-b2d2-42e19b1b1bc9] 2024-11-17T17:26:45.976368411Z [d1968adc-03c5-4e53-b2d2-42e19b1b1bc9] app/views/layouts/public.html.erb:6
相关代码与配置
布局文件(app/views/layouts/public.html.erb)
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %> <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
Gemfile片段
gem "dartsass-rails" gem "importmap-rails" gem "propshaft"
生产环境配置(config/environments/production.rb)
config.public_file_server.headers = { "cache-control" => "public, max-age=#{1.year.to_i}" } config.public_file_server.enabled = true
Kamal部署配置(config/deploy.yml)
# Bridge fingerprinted assets, like JS and CSS, between versions to avoid # hitting 404 on in-flight requests. Combines all files from new and old # version inside the asset_path. asset_path: /rails/public/assets
排查与解决步骤
1. 验证容器内预编译资产目录
进入容器后,检查public/assets目录(Propshaft生产环境默认读取路径)是否存在目标资产:
kamal app exec -i bash # 进入容器后执行 ls /rails/public/assets
如果该目录为空或没有application.css(或带指纹的版本),说明资产预编译步骤未正确执行。
2. 完善Dockerfile的资产预编译流程
确保Dockerfile中包含生产环境下的资产预编译步骤,示例:
# 设置生产环境变量 ENV RAILS_ENV=production # 安装依赖后执行预编译 RUN bundle install --without development test RUN bundle exec rails assets:precompile assets:clean
预编译会将app/assets/builds中的编译文件复制到public/assets并生成指纹文件,供Propshaft在生产环境读取。
3. 确认Propshaft加载路径配置
在config/initializers/assets.rb中,确保包含编译后的资产目录(可选,针对开发环境,但生产环境依赖预编译到public的文件):
Rails.application.config.assets.paths << Rails.root.join("app/assets/builds")
4. 检查生产环境资产配置
确保config/environments/production.rb中的核心配置正确:
config.assets.digest = true # 开启资产指纹(默认已开启) config.assets.compile = false # 生产环境禁止动态编译(默认已关闭)
5. 验证Kamal资产共享配置
当前config/deploy.yml中的asset_path: /rails/public/assets配置正确,该配置会在部署时合并新旧版本的资产目录,避免请求404,但前提是预编译后的资产已存在于该目录。
内容的提问来源于stack exchange,提问作者port5432
相关产品推荐
相关产品推荐

