Uploading Rails Project to AWS

Nicky Liu
Future Vision
Published in
5 min readApr 10, 2019

When deploying a project to Heroku, one thing I noticed was that the amount of rows I had for my back-end quickly exceeded the permitted amount. It was possible to increase the size via payment, but since most companies nowadays used Amazon Web Services and it’s cheaper, I figured I would deploy my backend there instead. It was quite a complicated process where I had to google a countless amount of errors, so I will layout the steps I made to upload the back end as well go over some of the errors that I faced and how to solve them.

Start by clicking on this link: https://aws.amazon.com/ec2/ . It will lead you to the Amazon Elastic Compute Cloud, which is what we will be using.

Then click on the “try amazon EC2 for free” button on the right hand side. This will lead you to the AWS Management Console page.

Click “all services” to expand the page, then under “Compute” select “EC2” and “Launch Instance” . This will take you to “Step 1: Choose an Amazon Machine Image (AMI)”. Select the first one (Amazon Linux 2 AMI (HVM), SSD Volume Type) on 64-bit (x86).

You will now be on “Step 2: Choose an Instance Type”. Select the second one “General purpose, t2.micro” (the one with Free Tier Eligible), and hit “Next: Configure Instance”.

You can ignore the next 3 menus, hit “Next: Add Storage”, then “Next: Add Tags”, then “Next: Configure Security Group”.

You will now be on “Step 6: Configure Security Group”. Enter a name for the Security Group, then under source select “Anywhere”. This allows you to connect your terminal to the terminal of the AWS cloud.

Click “Review and Launch” then“Launch”.

Select “Create a new key pair”, enter a name, and click “Download Key Pair”, then “Launch Instances”.

Return to the console and click “EC2”. Click on “running instances” to find your newly created database.

Copy the ip under “IPv4 Public IP”. Find the keypair that was saved earlier and move it to the Desktop if it isn’t already. Type the following code:

chmod 400 ~/Desktop/(key-pair-name).pem

Then:

ssh -i ~/Desktop/(key-pair-name).pem ec2-user@(ipAddress)
  • Note do not include the () in the above line of code

You should now be connected on your Terminal.

However, if you try running any commands you see that this environment doesn’t have a lot of things it can do. We need to set it up with ruby and rails and other stuff to get things working.

Start by installing git.

sudo yum install -y git gcc openssl-devel readline-devel zlib-devel

Now set up ruby.

git clone https://github.com/rbenv/rbenv.git ~/.rbenvecho 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile~/.rbenv/bin/rbenv initsource ~/.bash_profileeval "$(rbenv init -)"type rbenvgit clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-buildrbenv install ruby (latest version)rbenv global (latest version)gem install bundlergit clone git://github.com/dcarley/rbenv-sudo.git ~/.rbenv/plugins/rbenv-sudosudo yum groupinstall "Development tools" - to install gcc compilersudo yum install sqlite-devel

Now everything is set up.

Copy your project over from github.

git clone (repository link)

Cd into your project.

bundle 

If you get an error that says:

ruby version (version number) is not installed (set by /x/y/z)

Run

rbenv install (version number specified above)

If you get an error that says:

The 'bundle' command exists in these versions: 
(version number)

Do:

gem install bundler
gem update --system

Install Brew and Postgresql.

sudo yum install postgresql-develbundlegem install aws-sdksh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)brew install gccbrew install postgresql

Almost done!

Now to start postgres:

pg_ctl -D /home/linuxbrew/.linuxbrew/var/postgres start

You will get something like:

waiting for server to start....2019-04-14 02:58:11.245 UTC [28321] LOG:  listening on IPv4 address "127.0.0.1", port 54322019-04-14 02:58:11.248 UTC [28321] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"2019-04-14 02:58:11.259 UTC [28322] LOG:  database system was shut down at 2019-04-14 02:53:25 UTC2019-04-14 02:58:11.262 UTC [28321] LOG:  database system is ready to accept connections

Now run the following command to start up your server!

rails s -p 3001 -b 0.0.0.0

Go to your website.

(link after "Public DNS (IPV4)"):3001# something like:
ec2-34-220-205-226.us-west-2.compute.amazonaws.com:3001

It freezes. We forgot to allow the port 3001. Go back to the security group we used earlier. Click on add, select Type: “Custom TCP Rule” Port Range: “3001”, and Source: “anywhere” and save.

Now we should be all done!

But wait, now I got an error that says:

could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL/5432"

But let’s look again at the message we got earlier when starting the server.

waiting for server to start....2019-04-14 02:58:11.245 UTC [28321] LOG:  listening on IPv4 address "127.0.0.1", port 54322019-04-14 02:58:11.248 UTC [28321] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"2019-04-14 02:58:11.259 UTC [28322] LOG:  database system was shut down at 2019-04-14 02:53:25 UTC2019-04-14 02:58:11.262 UTC [28321] LOG:  database system is ready to accept connections

See the problem? It says “listening to Unix on socket “/tmp/.s.PGSQL.5432” while our website says “/var/run/postgresql/.s.PGSQL/5432”.

So now we need to make a link between the two. First create the directories.

sudo mkdir /var/run/postgresql

Now we link the two with:

sudo ln -s /tmp/.s.PGSQL.5432 /var/run/postgresql/.s.PGSQL.5432

Now if we again run:

rails s -p 3001 -b 0.0.0.0

The website works!

If this was a normal rails app this would be good, and if its a database you can run the standard commands to set it up before doing rails s again:

rails db:create
rails db:migrate
rails db:seed

Setting that up was a pain, but there is a way to save it: the Amazon AMI.

When we set up our first instance we used a base AMI, but we can use the AMI we made for an instance to start another instance.

Click on “instances” and select the instance you just made. Then select “image”, then “create image”. This saves the environment and allows you to use it to start other instances. To start another EC2 instance with this environment click on “instances” under “AMI”, click the instance you created and select “launch”, then repeat all the earlier steps of creating an instance (although now you can use the keypair you created from earlier instead of creating a new one).

Now one final problem. Everything works, but if you ssh out the rails server stops getting hosted. You can just leave your computer and terminal on forever, but most people generally don’t want to do that. So instead you can use “nohup” command. This command allows a process to run in the background instead.

So you can run your earlier rails command with “nohup” in the front and “&” in the back instead.

nohup rails s -p 3001 -b 0.0.0.0 &

The & sign at the end prints out the PID for you in the line after. So if you later want to stop the server hosting process just run:

kill PID

Now you have your app up, have a way to easily create new ones with the proper settings, and can host it without having to keep rails s open! Have fun deploying projects to AWS now, and hopefully you have an easier time than I did!

--

--