Running rails with external assets_host and path

I’m trying to use a cdn for deployment of application assets, and I"d like to be able to maintain multiple versions of these assets in the cdn, so when we do new deploys, the application can request the new versions of the assets, and we can easily test our and/or roll back between multiple versions of assets when different apps get deployed. To do so, I’m setting up an s3 bucket with prefixes corresponding to version numbers of the application, IE: /v1.2.3/packs, /v1.2.3/assets, etc.

For assets compilation, we’re using - rails asset pipeline, shakapacker, and dart-sass (part of pipeline).

What would be the recommended configuration to achieve this setup? I’ve been trying different combinations of config.assets.prefix and config.asset_host and have had different levels of success but nothing that has completely worked for all cases yet.

Test Case 1:

  • Set prefix to /assets
  • Set asset_host to cdn.url.com/v1.2.3/
  • upload files from public/ → s3://bucket/v1.2.3/

Outcome:

  • shakapacker assets work fine
  • rails assets (compiled css) references files /assets/* instead of /v1.2.3/assets/*

Test Case 2:

  • Set prefix to /v1.2.3/assets
  • Set asset_host to cdn.url.com
  • upload files from public/v1.2.3/ → s3://bucket/v1.2.3/

Outcome:

  • rails assets get put in /public/v1.2.3/assets which isn’t ideal but acceptable
  • rails assets load correctly from public cdn
  • shakapacker assets get put in /public/packs
  • shakapacker assets do not load correctly in this case

Other:

We are currently on rails 7.0. Shakapacker is updated to 7.2.2

To solve this problem of hosting assets on a cdn in side a subdirectory, here’s what I found out. Before building, set environment variable RAILS_RELATIVE_URL_ROOT=/prefix. This sets the build prefix for the css so that all the paths are prefixed with the specified path.

Build assets bundle exec rake assets:precompile --trace

Upload public/* to the cdn

On the production application host, set environment variable ASSET_HOST=https://cdn.url.com/prefix