Problem:
I'm running out of RAM while performing the rake assets:precompile
task in an automated build. Are there any strategies to do an incremental precompile, or in some other way perform the precompile stage without consuming as much RAM? It appears as though that task consumes around 850 MB more than the baseline for the build.
Context:
I'm trying to get a single Docker container Bitbucket Pipelines version of our automated build. Application stack includes Rails 4.2.7, PostgreSQL 9.3, Java 8, Maven 3.3.9 and JRuby 9.1.2.0. I've tried creating the image based off of Debian Jessie and also off of Alpine Linux, but it doesn't make much difference in the baseline memory.
rake assets:precompile. We use rake assets:precompile to precompile our assets before pushing code to production. This command precompiles assets and places them under the public/assets directory in our Rails application.
To compile your assets locally, run the assets:precompile task locally on your app. Make sure to use the production environment so that the production version of your assets are generated. A public/assets directory will be created. Inside this directory you'll find a manifest.
Use NodeJS as the JavaScript interpreter for precompiling (or another JavaScript interpreter characterized by low peak RAM usage).
For context, I'm using NodeJS 4.5.0 as compared to therubyracer v0.12.2 and therubyrhino v2.0.4
Sounds dumb, but before complicating the build process it may make sense to see if more capable build machines are available, or if swap space is available (although it will likely increase build times).
High peak RAM utilization seems to be a fundamental characteristic of both therubyrhino (Mozilla's Rhino JavaScript interpreter) and therubyracer (V8 JavaScript interpreter). There does not appear to be an effective way to significantly drop the amount of RAM consumed during the asset precompilation stage. The most viable paths appear to be precompiling the assets outside the build lifecycle and caching them somewhere so they can be fetched instead of precompiled, as suggested by @user4776684. As comments on the question suggest, both Rails version and Ruby version have an impact, but not nearly as much as the JavaScript interpreter.
As @slowjack2k mentioned above, if using Bundler, a parallel configuration can be leveraged to invoke NodeJS only for the precompile task and keep the original build relatively untouched. I didn't look into this as it was easier to switch interpreters, but while I was able to precompile the assets with rake and NodeJS, they didn't appear to be considered precompiled when it came to the rake + therubyrhino invocation so they were re-precompiled. I accomplished this with a programatically set BUNDLE_GEMFILE
environment variable which pointed to a completely separate gemfile, which used MRI Ruby and NodeJS instead of JRuby and therubyrhino.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With