Techioz Blog

プリコンパイルされたアセットを 0 バイトとしてロードするシン Web サーバー

概要

nginx が Docker コンテナから提供している Rails 7.0 アプリケーションを持っています。 Sprockets と Esbuild を使用して、これらのアセットを application.css と application.js にバンドルし、public/assets/application-.css と public/assets/application--.js にダイジェストしています。

これはうまく機能しています。public/assets の Docker コンテナで見つけたアセットには、何らかの種類のコンテンツが含まれています (ダイジェストされているため、読みにくいです)。

奇妙なのは、これらのアセットが Thin (私のレールには Web サーバーが含まれていました) によってブラウザに提供されているにもかかわらず、これらのアセット ファイルのバイト数がゼロであることです。これには、application-.css ファイルと application-<hash.js ファイルの両方に加え、すべてのイメージが含まれます。

もう 1 つ指摘しておきたいのは、このアプリケーションはローカルの Docker コンテナ上で実行されているため、Nginx とは何の関係もないということです。

さて、これは奇妙です。参考までに私のステージング構成を示します。何かアイデアはありますか?

 # Settings specified here will take precedence over those in config/application.rb

  # Configures whether Rails should serve static files from the public directory.
  config.public_file_server.enabled = true

  # Configures whether all registered config.eager_load_namespaces should be loaded at compile-time. This includes your application, engines, Rails frameworks and any other registered namespace.
  config.eager_load = true

  # Code is not reloaded between requests
  config.cache_classes = true

  # Configures whether or not to show helpful development messages on error
  config.consider_all_requests_local = false

  # Enable fragment caching (https://guides.rubyonrails.org/caching_with_rails.html#fragment-caching)
  config.action_controller.perform_caching = true

  # Configures Rails itself to serve static files
  config.serve_static_files = false

  # Compress javascripts and css
  config.assets.compress = true

  # Specify whether or not to fall back to Sprockets if precompiled assets aren't loaded
  config.assets.compile = false

  # Generate digests for assets URLs.
  config.assets.digest = true

  # Send logs to Docker STDOUT
  config.logger = Logger.new('/proc/1/fd/1')

  # Doesn't actually send mail
  config.action_mailer.perform_deliveries = false

  # The production environment is meant for finished, "live" apps.
  # Code is not reloaded between requests
  config.cache_classes = true

  # Full error reports are disabled and caching is turned on
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  # Specifies the header that your server uses for sending files
  config.action_dispatch.x_sendfile_header = "X-Sendfile"

  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
  # the I18n.default_locale when a translation can not be found)
  config.i18n.fallbacks = true

  # Send deprecation notices to registered listeners
  config.active_support.deprecation = :notify

  config.action_mailer.raise_delivery_errors = false

解決策

問題は次の行にありました。

 # Specifies the header that your server uses for sending files
 config.action_dispatch.x_sendfile_header = "X-Sendfile"

x_sendfile_header に関する Rails の公式ドキュメントによると、これはファイルから提供されている本文をインターセプトし、サーバー固有の X-Sendfile ヘッダーに置き換えます。

あまり深く掘り下げずに説明すると、これはおそらく、Rails の代わりに Nginx にアセットを提供することに関連するものですが、それは私がやっていることではありません。

いずれにせよ、これを削除すると、ブラウザは public/ から取得すると予想されるコンテンツを含むファイルを受信するようになります。