Ruby on Rails CORS setup for Heroku with Passenger 5.1.0

Ruby on Rails CORS setup for Heroku with Passenger 5.1.0

This is an update from a previous article about passenger 5.0.28.

These are the steps I used to setup for 5.1.0 they have changed a bit:

1. Copy the passenger’s ngnix config

Do this in the root directory of your Rails application.

cp $(passenger-config about resourcesdir)/templates/standalone/config.erb config/passenger_config.erb

2. Find passenger's default asset setup

Find the line:

<%= include_passenger_internal_template('rails_asset_pipeline.erb', 8, false) %>

3. Add your custom CORS config about the rails_asset_pipeline line

My configuration looks like this:

    server {
        <%= include_passenger_internal_template('server.erb', 8, true, binding) %>
        location ~ "^/assets/.+\.(woff|eot|svg|ttf|otf).*" {
            error_page 490 = @static_asset_fonts;
            error_page 491 = @dynamic_request;
            recursive_error_pages on;

            if (-f $request_filename) {
                return 490;
            }
            if (!-f $request_filename) {
                return 491;
            }
        }

        location @static_asset_fonts {
            gzip_static on;
            expires max;
            add_header Cache-Control public;
            add_header ETag "";
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, HEAD, OPTIONS';
            add_header 'Access-Control-Allow-Headers' '*';
            add_header 'Access-Control-Max-Age' 3628800;
        }
        <%= include_passenger_internal_template('rails_asset_pipeline.erb', 8, false) %>
    }

Notice how my configuration goes between <%= include_passenger_internal_template('server.erb', 8, true, binding) %> the block and include_passenger_internal_template('rails_asset_pipeline.erb', 8, false) block.

4. Update the Procfile

The Procfile should be changed to look something like this:

web: bundle exec passenger start -p $PORT --max-pool-size $WEB_CONCURRENCY --nginx-config-template ./config/passenger_config.erb

5. Deploy

Next you will need to deploy this new setting to Heroku.

6. Check out the header with curl

Open your site in Chrome and go to the network panel. You can filter the assets by 'Font'. Select one of the URLS for one of your font file. If you have Cloudfront configured properly, it will look something like https://afec098982.cloudfront.net/assets/fontawesome-webfont-82e18d70ffda5f198cc31bfb026dfa78.woff2?v=4.5.0. Replace the cloudfront domain with your heroku app domain and do a curl command that looks something like this:

curl -s -D - https://my-cray-cray-app.herokuapp.com/assets/fontawesome-webfont-82e18d70ffda5f198cc31bfb026dfa78.woff2?v=4.5.0 -o /dev/null

If everything is setup right, you should see a response that includes Access-Control-Allow- headers:

  HTTP/1.1 200 OK
  Connection: keep-alive
  Server: nginx/1.10.0
  Date: Fri, 13 May 2016 01:54:05 GMT
  Content-Type: application/octet-stream
  Content-Length: 66624
  Last-Modified: Mon, 29 Feb 2016 21:58:39 GMT
  Expires: Thu, 31 Dec 2037 23:55:55 GMT
  Cache-Control: max-age=315360000
  Cache-Control: public
  Access-Control-Allow-Origin: *
  Access-Control-Allow-Methods: GET, HEAD, OPTIONS
  Access-Control-Allow-Headers: *
  Access-Control-Max-Age: 3628800
  Accept-Ranges: bytes
  Via: 1.1 vegur