Skip to content

Instantly share code, notes, and snippets.

@schneems
Last active June 19, 2021 00:12
Show Gist options
  • Save schneems/9374188 to your computer and use it in GitHub Desktop.
Save schneems/9374188 to your computer and use it in GitHub Desktop.
I hate asset_sync

A not politically correct assertion of my feelings towards a piece of software:

Note: Repetition builds cynicism, asset_sync isn't bad, but when an asset problem cannot be solved via support it gets escalated to me. Often times someone using asset_sync the problem is due to their use of the library and not from Heroku.

Backstory

The asset sync gem uploads your assets (images, css, javascript) to S3. From there you can either point browsers to the copy on S3 or use a CDN + the S3 bucket. It's a good idea, and solved a problem at one time.

It is no longer needed and you should now use https://devcenter.heroku.com/articles/using-amazon-cloudfront-cdn instead. So rather than copying your assets over to S3 after they are precompiled the CDN grabs them from your website instead. Here's some reasons why it's better.

Begin Rant

Cannonical Assets

I like Ruby, and I like Rails. The concept of keeping your code DRY is more than good practice it allows you to have single authoritive places of information. If you need to change that information you change it in one place and that's it. With asset_sync we're saying that although our "cannonical" copy of assets is in our source control, we're now relying on a 3rd party store of assets. What happens if someone has a failed deploy after assets get synced, what if someone modifies a file in the S3 bucket? Instead of fixing one copy of assets now you must fix two.

Deploy Determinism

If I'm debugging on my app inside of a dyno heroku run bash and I run rake assets:precompile this doesn't just modify my local copy, it actually modifies the copy on S3 as well. This goes back to cannonical stores, it can be bad. All your assets are screwed up and you don't know why. The sync part of asset_sync can also fail if S3 is down, or there's a glitch in the network. What if you only write part of a file, or only half of your assets are synced. These things happen

Do more with less

Now that you can have a CDN dynamically grab assets from your website there is no reason to add an extra step into the process. You 100% should be using a CDN as Ruby is horrible for serving assets, and S3 is only slightly better. If I asked you to move a bag of cement from a car to a construction site, you probably wouldn't feel very much like carying it to virgina first. This is essentially what you're doing when you're using asset_sync. It's not a bad step, but it's not a necessarry step either.

End Rant

Using asset sync can cause failures, is difficult to debug, un-needed, and adds extra complexity. Don't use it. Instead use https://devcenter.heroku.com/articles/using-amazon-cloudfront-cdn

I appreciate the authors of the software and everything asset_sync has allowed developers to do in the past. Now it's not needed so please don't use it.

ktksbye

@schneems

Comments

Comments on gists don't send notifications. You're basically shouting into the ether :(

@paulodeon
Copy link

https://devcenter.heroku.com/articles/using-amazon-cloudfront-cdn is not a complete solution as far as I can see. It doesn't describe at all how to set up the cloudfront distribution

@jstewart
Copy link

https://devcenter.heroku.com/articles/using-amazon-cloudfront-cdn is not a complete solution as far as I can see. It doesn't describe at all how to set up the cloudfront distribution

The AWS documentation is adequate. Basically, you set up a distribution which pulls from your server (serving static assets) as an origin. I just did this today and it was fairly simple. Bye, bye asset_sync!

@paulodeon
Copy link

What wasn't clear to me from the linked article is that the origin of the distribution is in fact the URL of your app. Once I realised that everything slotted into place. It is a complete solution and no need for asset_sync. Apologies for the FUD!

@KevinColemanInc
Copy link

we're saying that although our "cannonical" copy of assets is in our source control, we're now relying on a 3rd party store of assets

No, that is not typically how rails works. You don't commit the compressed assets to git, otherwise everytime you build them, your git history will be full of useless diffs (or new files if you use the checksum in the filename).

What happens if someone has a failed deploy after assets get synced

Nothing? don't delete the old assets and rollback the code.

What if someone modifies a file in the S3 bucket?

What if someone ssh's onto your ec2 box and modifies the source code? Don't do that. AWS has IAM roles that you can configure so that only the CI server has permission to modify s3 and your ec2 box.

Instead of fixing one copy of assets now you must fix two.

Why are you fixing things outside of git? Are you saying you ssh onto each server and modifying the code? S3 would be a single place where your assets are stored. If you have multiple web servers / dynos, then you have multiple locations of your assets.

If I'm debugging on my app inside of a dyno heroku run bash and I run rake assets:precompile this doesn't just modify my local copy, it actually modifies the copy on S3 as well.

How is this any different if you ran User.delete_all in production and you get mad when you lose your dyno modifies your postgres database?

The sync part of asset_sync can also fail if S3 is down, or there's a glitch in the network.

What if your server is down? Do you want all of your images (like in emails or direct links) to fail too?

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