Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fails when used with Docker and asset hosts defined by runtime environment variables. #13

Open
radicaled opened this issue Feb 17, 2016 · 0 comments

Comments

@radicaled
Copy link

Note: on Rails 4.1.8

Preface:

When using the in-memory Sprockets::Enviroment (or Sprockets::Index) object, the generated digests are based on the following: digest version and file contents. A digest version string sometimes looks like this: "development-1.0-2.2.0" => (rails environment)-(assets version)-(sprocket-rails gem version).

However, when you supply an asset host, a digest version string will look more like this: "development-1.0-assets.coolwebsite.io-2.2.0" => (rails environment)-(assets version)-(asset host)-(sprocket-rails gem version).

The digest version string affects the resulting digest of generated files during asset recompilation.

Assuming this line in a configuration file,

config.action_controller.asset_host = ENV['ASSET_HOST'] if ENV['ASSET_HOST']

then these are how the file digests change:

> $ RAILS_ENV=staging ASSET_HOST=assets.coolwebsite.io rake assets:precompile
I, [2016-02-17T13:02:01.915233 #7877]  INFO -- : Writing /app/public/assets/constants-b6b723e4db1e240438bee7dae6205e72.json

> $ RAILS_ENV=staging rake assets:precompile
I, [2016-02-17T13:04:39.076350 #7938]  INFO -- : Writing /app/public/assets/constants-a3b2140a0038d4707424f453d279e072.json

Problem:

If you're using Docker (or any other kind of isolated container system), you're probably not going to set your ASSET_HOST environment inside of your Dockerfile, since that will change from staging environment to qa environment to production environment.

In that case, rake assets:precompile will generate digests and a manifest file that uses those digests without considering the asset host. This will work fine in staging / production, since Rails will get the logical mappings from the generated manifest file on disk and not the in-memory Sprockets::Index, but any third-party code that introspects Sprockets::Environment and Sprockets::Index will fail to use the right digests: now that ASSET_HOST is defined in the running container, the digest version string has changed from something like "development-1.0-2.2.0" => "development-1.0-assets.coolwebsite.io-2.2.0", resulting in a different file digest than the one on disk. Sprockets::Environment/Index calculates the digest in memory instead of reading from the manifest file on disk.

So, the technique that sprockets-redirect uses doesn't quite work with most uses of Docker (and possibly other isolated build systems). Took me about two hours to track down why this was working locally but not in production -- even if this can't be fixed, I hope it helps anyone else stumbling across it. Especially my future self, who will forget everything about this problem in around two months.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant