If you use AWS, a small change can help you save money and gain better performance.
AWS launched AWS Graviton that are custom built by Amazon and use ARM based processors. They use less energy and are better price performant1. If you know about Apple M1 and its performance then you are already aware of the power of ARM processors.
There is enough material available on the Internet on how to deploy a Ruby on Rails on x86/Intel based processors, however, preparing an AWS Graviton EC2 instance for Ruby on Rails is slightly different.
In this post we will prepare an AWS Graviton EC2 instance for Ruby on Rails deployment. In later posts we will cover:2
- Setting up Puma & Nginx
- Setting up Puma & Sidekiq as systemctl services for easy management
- Setting up Capistrano for easy deployment
- We will use Ubuntu as the OS.
- We will use RVM
- We will use Sidekiq as our ActiveJob processor
- We use PostgreSQL on RDS and will install only the client on the instance
- We will use Puma as application server and Nginx in front of Puma
Create a Graviton based EC2 instance from AWS Console, and ssh into it
sudo apt-get update sudo apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
You need to add a custom repository to install RVM, and that also requires adding GPG keys. Check RVM website to get current keys.
gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB sudo apt-get install software-properties-common sudo apt-add-repository -y ppa:rael-gc/rvm sudo apt-get update sudo apt-get install rvm sudo usermod -a -G rvm ubuntu
Log out and log in to the machine again.
We will use Ruby 2.7.2, however you can choose to install any version that is relevant for you.
rvm install 2.7.2 rvm use 2.7.2 rvm use --default 2.7.2
Install Node.js & Yarn
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - # Adding Yarn repository curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get update sudo apt-get install nodejs yarn
Install PostgreSQL and Redis Clients
sudo apt-get install postgresql-client sudo apt-get install redis-tools
This command is a bit specific for ARM processors, take care to use this exact command
sudo apt-get install imagemagick --fix-missing
sudo apt-get install nginx
Install Gems that require custom setup for AWS Graviton
This one took a while for us to figure out
gem install bundler gem install sassc --version=2.4.0 -- --disable-march-tune-native
sudo apt-get install libpq-dev gem install pg -v '1.2.3
The simplest way to set environment variables is to place them in /etc/environment file
# set env variables in /etc/environment export RAIL_ENV=production export RACK_ENV=production export DATABASE_URL=postgresql://DB_USERNAME:DB_PASSWORD@host:5432/DB_NAME export RAILS_MASTER_KEY= export RAILS_SERVE_STATIC_FILES=enabled export REDIS_URL=redis://REDIS_HOST:6379 export rvmsudo_secure_path=1
Please take care to
- Create a valid
DB_NAMEIf your database uses a different port than
5432, take care to replace that too.
REDIS_HOST. If your redis server runs at a different port than
6379, replace that as well.
At this point, you should have your EC2 instance ready for Ruby on Rails app, and you can use your favourite mechanism to deploy code to the machine.
Although AWS is very different from other VPS providers, there are a lot of things you can do better, in terms of your workflow as well as security. Having spent 10+ years using Cloud Providers like AWS and GCP, and a couple of years managing them, I know AWS can be very overwhelming at first. However, if you deploy on AWS, your infrastructure growth will be more cost effective and better handled in the longer term.
We can also open source our Terraform scripts that can help you create production grade infrastructure on AWS in a matter of minutes. Soopr API is built using Elixir/Phoenix and can write about how to deploy an Elixir/Phoenix app on AWS. Let us know on twitter if you are interested in any of these topics. ↩