Rails 6 on Elastic Beanstalk

This article is designed to cover & fix some of the issues when attempting to run a Ruby on Rails 6 on AWS Elastic Beanstalk.

The Quick Version (TLDR)

  • Create directory .ebextensions in the top level of your application
  • Create .config file which contains the commands to fix deployments (script here)
    • Add commands for upgrading nodejs to >=6.14.4
    • Add container commands to install webpack & precompile assets
  • Disable asset building through elastic beanstalk
    • set set RAILS_SKIP_ASSET_COMPILATION to True
  • Deploy (wait 5 – 7 min for steps above to complete)

The Detailed Version

Configuration

First the setup:

  • I was upgrading from Rails 5.2 to Rails 6
  • ElasticBeanstalk Platform: Puma with Ruby 2.5 running on 64bit Amazon Linux/2.11.0
  • This was for: demo.InsiderOpinion.com

Rails 6 on Elastic Beanstalk – Nodejs Issue

The primary issue was that when upgrading I did my standard deployment “eb deploy” — unfortunately, on this deployment I got “502 Bad Gateway Error” when I visited the page.

Quickly I try to grab some logs… and it bugs out, no logs. Usually, this means the server never launched and had an error some where on deployment. Luckily, I have Elastic Beanstalk configured such that I can SSH into the machine. After accessing the machine I ran cat /var/log/eb-activity.log and it shows me everything I need.

Turns out I’m experiencing issues from the new Webpacker default for Javascript compilation:

Webpacker requires Node.js >= 6.14.4 and you are using 4.6.0
Please upgrade Node.js https://nodejs.org/en/download/ (Executor::NonZeroExitStatus)

Cool AWS, using NodeJS from 2016:

To upgrade I found a StackOverflow discussion, creating a .ebextensions/ directory in the top level of the project and adding the following file to said .ebextensions/ directory:

Note, we are installing yarn & nodejs on the instance itself via the commands. This will deploy along with my application and be executed on the instance.

Rails 6 on Elastic Beanstalk – Asset Compiling Issue

Once I added it, I Tried to deploy again and again:

Well, that’s frustrating – lets look at the logs again:

[Application deployment StartupStage0/AppDeployPreHook/11_asset_compilation.sh] : Activity execution failed, because: ++ /opt/elasticbeanstalk/bin/get-config container -k script_dir

…..

[Application deployment] : Completed activity. Result: Application deployment – Command CMD-SelfStartup failed

Not much explanation there, but I’m suspecting it’s still related to the Webpacker. After from more DuckDuckGo-ing, I found this Reddit discussion, recommending disabling asset building (set RAILS_SKIP_ASSET_COMPILATION to True) and adding it to the .ebextensions/ directory (again):

Added and redeployed! Progress was definitely made (confirming it was the Wepacker changes), but now assets don’t appear built at all:

Woah – that’s not right! It appears as if the assets aren’t being compiled.

Rails 6 on Elastic Beanstalk – Webpack not found

Huh… SSHing back in I find:

error Command “webpack” not found.
(ElasticBeanstalk::ExternalInvocationError)

At this point, my mental state can be summed up best by a meme:

Webpacker was already present in my Gemfile (version 4.0.7), apparently it also needs to be installed on the container. This simply means adding a single line to install webpack on the container, bringing our container_commands in our ebextensions/ config to two lines:

Moment of truth, deploy again & wait:

Finally! It appears to function as intended, what a glorious sight. It’s important to keep in mind, all of these steps are outside the normal process and it takes quite a bit of time to install (on the order of 5 – 7 min). The whole configuration script is as follows:

Rails 6 on Elastic Beanstalk – Closing Thoughts

I just want to place emphasis – I would not recommend using Elastic Beanstalk. Having said that, clearly I use it. The main issue I have is how “janky” the system is. For my development it helps me scale well, as I have between five to seven microservices running at any given time. However, if possible, avoid Elastic Beanstalk – I’m sure you can see why.

Some of these issues can be mitigated by creating docker containers and deploying them. Admittedly, that would be easier, but this is my current set up.

Anyway, hope this helps!

Related Articles

3 thoughts on “Rails 6 on Elastic Beanstalk

  1. Thanks for the write-up! Do the versions of node in the URLs for part 01 and part 02 need to be the same?

    I’m having similar issues upgrading a Rails site from 5.2 to 6.0. I need to upgrade to Ruby 2.6 at the same time so I’m trying to deploy a new environment, but I keep getting error after error.

    Maybe it’s time I bite the bullet and convert the site to Docker. I’d been resisting it since it’s pretty sluggish on mac OS, but when Elastic Beanstalk breaks it sure does break!

  2. Thanks so much for this, it was incredibly helpful. A few notes from my experience implementing your script in our beanstalk environment: (see https://gist.github.com/mattlima/096aa95f1779c809a628cca2f53fd28e for what worked for me)
    1) the webpacker node task defaulted to the v6 NodeJS runtime (v6 is installed on line 4 of your gist) and would fail because it requires v8. The solve was to install node v8 first, then install yarn, without the curl command that adds the v6 repo.
    1a) We ended up having to add
    /bin/rm -rf /var/cache/yum && /usr/bin/yum remove -y nodejs && /bin/rm /etc/yum.repos.d/nodesource* && /usr/bin/yum clean all
    as a first command after the script failed once in order to clean up the old v6 runtime. Someone running the updated version linked above probably wouldn’t need this.
    2) Webpacker was complaining about not finding babel-source and webpack-cli on the container, even though they’re in yarn.lock, so we had to explicitly add them to our package.json file in order for the assets:precompile task to succeed.
    3) Lastly, we were running into strange failures on small EC2 instances which turned out to be out of memory errors. Running rails and webpack at the same time eats up a bunch of RAM. We couldn’t run this on a t3.nano instance. Switched to t2.medium and all was well.

    Thanks again!

Leave a Reply

Your email address will not be published. Required fields are marked *

 characters available

Time limit is exhausted. Please reload the CAPTCHA.