Skip to content

Instantly share code, notes, and snippets.

@j-mcnally
Last active January 24, 2017 10:45
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save j-mcnally/11163883 to your computer and use it in GitHub Desktop.
Save j-mcnally/11163883 to your computer and use it in GitHub Desktop.
Sample ElasticBeanstalk Config for Rails 3 on Puma and Using a bundle / gems cached on s3 for faster scaling.

Quick / Cached Bundles on ElasticBeanstalk

Bonus, support Rack 1.4.5 with puma for Rails 3 apps

Basically we bundle install on one box, upload the result to a dedicated s3 bucked and then other servers/nodes can download the gems and save a ton of time compiling them.

I can not stress enough how the bucked should be dedicated as it will often remove all the files in the bucket to clear the cache / do a new gem build each month incase changes are made to backing ami / software, you can adjust the prefix to clear the bundle "cache key" more frequently by appending more date modifiers such as day or hour if you run into issues.

Note: You can remove 14downgradepuma if your app runs on Rails 4

option_settings:
- option_name: BUNDLE_DISABLE_SHARED_GEMS
value: "true"
- option_name: BUNDLE_PATH
value: "vendor/bundle"
- option_name: RAILS_SKIP_ASSET_COMPILATION
value: "true"
- option_name: RAILS_SKIP_MIGRATIONS
value: "false"
packages:
yum:
git: []
ImageMagick: []
ImageMagick-devel: []
libmemcached: []
libmemcached-devel: []
gcc: []
libstdc++-devel: []
gcc-c++: []
libcurl-devel: []
libxml2-devel: []
openssl-devel: []
mailcap: []
make: []
files:
"/opt/elasticbeanstalk/hooks/appdeploy/pre/10_bundle_install.sh":
mode: "000700"
owner: root
group: root
content: |
#!/bin/bash
# Do nothing
"/opt/quick_bundle":
mode: "000700"
owner: root
group: root
content: |
#!/bin/bash
echo "==================$(date -u)===================="
bundle_path="/var/app/shared"
prefix="`date +%Y%m`"
awscmd="aws"
gem_s3_bucket="DEDICATED-S3-BUCKET-FOR-GEMS"
makebundle="/usr/local/bin/bundle install --gemfile $EB_CONFIG_APP_ONDECK/Gemfile --path $bundle_path/bundle --without $BUNDLE_WITHOUT --deployment"
existing="$awscmd s3 ls s3://$gem_s3_bucket"
echo $existing
existing=`$existing | grep -i $prefix-bundle.tar.gz`
if [ -z "$existing" ];
then
echo "Gem file does not exist"
# Remove all old packages
$awscmd s3 rm s3://$gem_s3_bucket/ --recursive
# Do some tar thing
# Run bundle
$makebundle
chown webapp:webapp -R $bundle_path
cd $bundle_path
tar -zcvf $prefix-bundle.tar.gz bundle
md5 -q $prefix-bundle.tar.gz >> /tmp/bundle-checksum
$awscmd s3 cp $prefix-bundle.tar.gz s3://$gem_s3_bucket/
$awscmd s3 cp /tmp/bundle-checksum s3://$gem_s3_bucket/
rm $prefix-bundle.tar.gz
rm /tmp/bundle-checksum
echo "Bundle uploaded"
else
echo "Gem file exists"
# Download existing package
# Check md5 of downloader tar gz to make sure we're not intransit
# Do 3 tries for consistency
for i in `seq 1 3`;
do
$awscmd s3 cp s3://$gem_s3_bucket/$prefix-bundle.tar.gz $bundle_path/bundle.tar.gz
$awscmd s3 cp s3://$gem_s3_bucket/bundle-checksum /tmp/bundle-checksum
md5_fingerprint=`cat /tmp/bundle-checksum`
my_md5=`md5 -q $bundle_path/bundle.tar.gz`
if [ "$md5_fingerprint"="$my_md5" ];
then
echo "MD5 matched!!!!"
cd $bundle_path
tar zxvf $bundle_path/bundle.tar.gz
rm $bundle_path/bundle.tar.gz
rm /tmp/bundle-checksum
$makebundle
chown webapp:webapp -R $bundle_path
exit 0;
else
echo "MD5 mismatch, wait 30 seconds."
sleep 30
fi
done
rm $bundle_path/bundle.tar.gz
rm /tmp/bundle-checksum
puts "Could not match md5 just bundle locally"
$makebundle
chown webapp:webapp -R $bundle_path
fi
container_commands:
06setuptemp:
command: mkdir -p $EB_CONFIG_APP_ONDECK/tmp
08removebundle:
command: rm -rf $EB_CONFIG_APP_ONDECK/vendor/bundle; return true;
ignoreErrors: true
09makebundle:
command: mkdir -p $EB_CONFIG_APP_ONDECK/vendor/bundle
ignoreErrors: true
10symlinkbundle:
command: mkdir -p /var/app/shared/bundle; chown webapp:webapp -R /var/app/shared; ln -s /var/app/shared/bundle $EB_CONFIG_APP_ONDECK/vendor/bundle
11bundleinstall:
command: /bin/bash -l -c '/opt/quick_bundle' >> /var/log/quickbundle.log
12fixperm:
command: chown webapp:webapp -R /var/app/shared
13fixperm2:
command: chown webapp:webapp -R $EB_CONFIG_APP_ONDECK
14downgradepuma:
command: yes | gem uninstall puma; gem install puma --version 2.6.0 --no-ri --no-rdoc; gem install rack --version 1.4.5 --no-ri --no-rdoc; yes | gem uninstall rack --version 1.5.2; killall -9 puma
ignoreErrors: true
command:
14trymigrate:
command: /var/app/shared/bundle exec rake db:migrate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment