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
Please note:
- 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
Installations
Create a Graviton based EC2 instance from AWS Console, and ssh into it
Update packages
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
Install RVM
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.
Install Ruby
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
Install ImageMagick
This command is a bit specific for ARM processors, take care to use this exact command
sudo apt-get install imagemagick --fix-missing
Install Nginx
sudo apt-get install nginx
Install Gems that require custom setup for AWS Graviton
sassc gem
This one took a while for us to figure out
gem install bundler
gem install sassc --version=2.4.0 -- --disable-march-tune-native
pg gem
sudo apt-get install libpq-dev
gem install pg -v '1.2.3
Environment Variables
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
DATABASE_URL
by replacingDB_USERNAME
,DB_PASSWORD
andDB_NAME
If your database uses a different port than5432
, take care to replace that too. - Add
RAILS_MASTER_KEY
- Add
REDIS_HOST
. If your redis server runs at a different port than6379
, 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.
Conclusion
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.
Footnotes
-
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. ↩