How to Deploy Rails 5.1 API only Backend App to Elastic Beanstalk

Create a Rails 5.1 api only app:

rails new pine --skip-spring -C -d postgresql --api

We don't need spring or ActionCable. Let's update brew and install aws-elasticbeanstalk command line utility:

$ brew update
$ brew install aws-elasticbeanstalk

Note: Elastic Beanstalk supports Ruby 2.3. They seem to be behind one major version for stability.

The Rails app has a health controller with index action that returns a status ok JSON:

{
  "status": "ok"
}

At each step of this process, add and commit the code in git. Run eb init:

$ eb init
Select a default region
1) us-east-1 : US East (N. Virginia)
Select an application to use
1)[ Create new Application ]
Enter Application Name
(default is "rails5app"):
Application rails5app has been created.
It appears you are using Ruby. Is this correct?
(y/n): y
Select a platform version.
1) Ruby 2.3 (Puma)
Do you want to set up SSH for your instances?
(y/n): y
Select a keypair.
1) [ Create new KeyPair ]
(default is 1): 1

Create the production environment:

$ eb create production

This will take some time, wait for an hour or so. You can check the status using:

$ eb status

We need to configure the SECRET_KEY_BASE.

$ eb setenv SECRET_KEY_BASE=$(rails secret)

Add 'pg' gem to Gemfile. Specify the production database values in database.yml:

production:
    adapter: postgresql
    encoding: unicode
    database: <%= ENV['RDS_DB_NAME'] %>
    username: <%= ENV['RDS_USERNAME'] %>
    password: <%= ENV['RDS_PASSWORD'] %>
    host: <%= ENV['RDS_HOSTNAME'] %>
    port: <%= ENV['RDS_PORT'] %>

We can now deploy the bare bones Rails 5.1 backend app:

eb deploy

The output shows:

Creating application version archive "app-4801-170728_225019".
Uploading pine/app-4801-170728_225019.zip to S3. This may take a while.
Upload Complete.
ERROR: Environment named production is in an invalid state for this operation. Must be Ready.

The environment is not ready yet. We can check the status:

eb status

The status shows that it is updating:

Environment details for: production
  Application name: pine
  Region: us-east-1
  Deployed Version: app-d013-170728_182048
  Environment ID: e-xwcn3dbsex
  Platform: arn:aws:elasticbeanstalk:us-east-1::platform/Puma with Ruby 2.3 running on 64bit Amazon Linux/2.4.2
  Tier: WebServer-Standard
  CNAME: production.pf3mj4j3zw.us-east-1.elasticbeanstalk.com
  Updated: 2017-07-29 05:49:24.003000+00:00
  Status: Updating
  Health: Green

After some time, the status is ready but in red state:

Environment details for: production
  Application name: pine
  Region: us-east-1
  Deployed Version: app-d013-170728_182048
  Environment ID: e-xwcn3dbsex
  Platform: arn:aws:elasticbeanstalk:us-east-1::platform/Puma with Ruby 2.3 running on 64bit Amazon Linux/2.4.2
  Tier: WebServer-Standard
  CNAME: production.pf3mj4j3zw.us-east-1.elasticbeanstalk.com
  Updated: 2017-07-29 05:52:48.346000+00:00
  Status: Ready
  Health: Red

Beanstalk Red status

I ran eb logs which seemed to hang (maybe it was downloading a zip file, only God knows because there is no feedback).

$ eb logs 
Retrieving logs...

I logged in to AWS console for Elastic beanstalk and downloaded the log files. I saw the following error in eb-activity.log:

PG::ConnectionBad: 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"?
/opt/rubies/ruby-2.3.4/bin/bundle:22:in `load'
/opt/rubies/ruby-2.3.4/bin/bundle:22:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace) (Executor::NonZeroExitStatus)

EB activity log

The cause of this problem was that I had created the Postgres database using CLI and by default it was in VPC.

Delete VPC RDS

So it was not accessible to the external Rails app. I had to create another RDS instance using the AWS console browser GUI.

Postgres

RDS Db details

RDS Postgres using Gui

Create RDS using Gui

Now the status went from red to yellow.

Beanstalk yellow status

In the root directory of the Rails app, create a folder called .ebextensions. In this directory, create a file called packages.config with the following contents:

packages:
  yum:
  postgresql93-devel: []

This must be installed for Postgres database to work. Commit the change to git and deploy.

eb deploy

The application will be now be uploaded to Beanstalk.

Creating application version archive "app-4801-170728_225337".
Uploading pine/app-4801-170728_225337.zip to S3. This may take a while.
Upload Complete.
INFO: Environment update is starting.                               
INFO: Deploying new version to instance(s).                         
 -- Events -- (safe to Ctrl+C) Use "eb abort" to cancel the command.

The eb status may say ready, but the GUI still shows as the update is in progress.

Elastic beanstalk green

Wait for the update to complete and run:

eb open

to open the Rails app in the browser. You will be able to see the status ok at elastic-url-opened-by-the-command/health/index.

Bigger Screenshots

You can view bigger screenshots here.


Related Articles