At Le Wagon, we use AWS Elastic Beanstalk to host the pedagogic platform used by hundrends of students across the world. This is a Rails 5.1 application using the latest niceties like ActionCable, Webpacker and Sidekiq. If you read my previous article, you know that the command to deploy is:
We have two instances behind a load balancer, with a one-at-a-time deployment strategy. When deploying, a first instance unregisters itself from the Load Balancer and stops serving production traffic. Then the deployer will push the new code and triggers a series of script. If you connect to one of the EC2 instance, you can have a look at them:
eb ssh ls -l /opt/elasticbeanstalk/hooks/appdeploy/pre/ -rwxr-xr-x 01_unzip.rb -rwxr-xr-x 02_setup_envvars.sh -rwxr-xr-x 03_mute_sidekiq.sh -rwxrwxr-x 101_yarn_setup.sh -rwxrwxr-x 102_yarn_install.sh -rwxr-xr-x 10_bundle_install.sh -rwxr-xr-x 11_asset_compilation.sh -rwxr-xr-x 12_db_migration.sh -rwxr-xr-x 13_test_for_puma.sh
102_yarn_install.sh are three tasks I added to support Sidekiq and Webpacker. The other scripts are the one installed by default when you create a new Ruby application on AWS Elastic Beanstalk.
Overall, AWS EB works quite well. But the documentation is scarce / uncomplete / outdated and we are miles away from the speed of a
git push heroku master. One reason is that by default, AWS EB won’t cache and re-use gems between two deployments. This means that for every
eb deploy, you wait for a full
bundle install to run, download every gems and install them. That’s pretty long.
Hopefully, thanks to the hooks sytem, you can write your own. That’s what I did. The idea is to copy the downloaded gems somewhere on the machine, and make sure to re-use that on the next deployments before running the
bundle install. You can also use this techniques for assets and reduce the time that
rake assets:precompile needs to run.
Here is the script you can take and drop in your
.ebextensions folder as a
This script is caching the content of the three following folders:
vendor/bundlewhich is built by
node_moduleswhich is built by the
yarn installcommand (Webpacker)
tmp/cache/assetswhich stores intermediate Sprocket files built by the
Go ahead and add this to your Rails app hosted on Elastic Beanstalk! We dropped the deployment time on two EC2 machines from 20+ minutes to ~8 minutes!