Skip to content

Instantly share code, notes, and snippets.

@schneems
Created August 11, 2014 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schneems/5dc42963fb3221a7a089 to your computer and use it in GitHub Desktop.
Save schneems/5dc42963fb3221a7a089 to your computer and use it in GitHub Desktop.

ActionDispatch::Static Purposes

What does ActionDispatch::Static do? It currently serves assets from the /public directory. It can serve asset pipeline assets as well as "unmanaged" assets you place in this directory.

  • Serving asset pipeline assets (managed under public/assets)
  • Serving non-asset pipeline assets (unmanaged, anywhere else)

It is possible for it to serve user uploaded assets (user uploads smile.png and it goes into /public and is served by Static), but this is not best practice in production, and the only time you would enable this is in production. Doing this makes it impossible to scale up to more than one server, therefore this is not a supported use of this middleware.

It can also be used to serve static html pages i.e. /public/index.html. While this is still technically under the "serving non-asset pipeline assets" it is a special enough case.

  • Serve static pages under /public

An exception to this is error pages. ActionDispatch::Static does NOT render exceptions. Instead ActionDispatch::PublicExceptions handles internal errors, this is how 500.html etc. is rendered. To manually issue an exception you render it yourself

(http://stackoverflow.com/questions/779784/how-do-you-issue-a-404-response-from-a-rails-controller-action) (http://stackoverflow.com/questions/2385799/how-to-redirect-to-a-404-in-rails)

On or Off

By default ActionDispatch::Static is off in production. To serve assets in production you either need to manually enable it or to serve your assets via a third party. The most common third party is NGINX which requires configuration and then it will serve assets directly before your Ruby/Rails server ever sees the requests.

  • NGINX: Keep ActionDispatch::Static off

People can use something like asset sync which I recommend against (https://gist.github.com/schneems/9374188) and push their content somewhere else like S3. In this case asset requests are never made to the Ruby/Rails server so we don't need it.

  • Asset Sync (or similar): Keep ActionDispatch::Static off

Using a CDN is the Fastest and best way to deliver assets period. Rails asset pipeline easily supports them. A CDN must know where to get an asset. You can either "push" to a CDN, an example would be using asset sync to push to S3 and putting a CDN in front of that S3 bucket. You can also have a CDN "pull" assets on demand. This is on first request there will be a cache miss and they will hit an origin URL (your rails server) for the asset. On all other requests they will serve the asset directly.

  • CDN "push": similar to Asset Sync keep ActionDispatch::Static off
  • CDN "pull": Asset is only ever served once, but our Ruby/Rails site must be able to serve the asset once, so ActionDispatch::Static should be turned on

Lastly you can serve the asset directly from your Ruby/Rails server, this is a horrible idea as it is slow and impacts the speed of other requests. Using this with a CDN is a pretty good idea as you will only serve the asset once then the CDN will serve the asset faster than you ever could, but having no caching is setting users up for a bad time

  • Self Serve (No CDN): Keep ActionDispatch::Static on

This last option is acceptable for hackathons, school projects, or anything else not expecting "serious" traffic. That being said adding a CDN is so quick and easy, and the gains are so great, I would not consider an application "production grade" if it does not have a CDN in front of it.

If you are running NGINX, you should still be running behind a CDN for data locality. In short you should be running behind a CDN regardless of how your assets are served.

NO pain Asset Serving

While there are a variety of ways to serve assets, is no need to incur a ActionDispatch "tax" on every request when we are not serving assets. Of the "on" cases there are only two:

  • CDN "pull": ActionDispatch::Static should be turned on
  • Self Serve (No CDN): Keep ActionDispatch::Static on

In this case for the "pull" we don't care if our asset is delayed by a few milliseconds while being served if it is only served once and is cached forever after that. In the case of "self serve" it is clear that the end user does not prioritize speed and would not be drastically impacted if a few milliseconds of delay were introduced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment