Don't miss

I created an open source development tool to quickly & dynamically mock API endpoints. Check it out at GitHub: DuckRails

Heads up

I will no longer maintain arubystory. For new posts, find me at my personal blog. CU there!

Sunday, December 22, 2013

Tutorial - Deploying the ToDo application to OpenShift - Ruby on Rails

In the previous three posts we created a simple ToDo application with Ruby on Rails. In this last part we are going to deploy the application to OpenShift. View the application deployed to Openshift.




You can find the complete code of the tutorial here.


OpenShift

OpenShift is an awesome cloud application platform (by Red Hat). Few months ago, when I was discovering Ruby & Ruby on Rails I started developing an application in order to practice. When I completed the first version I wanted to have it online for demonstration purposes and thus I started exploring my options. I decided really fast since I had a requirement that only OpenShift (at least at that time) could fulfil. Local storage. I wanted to allow users to upload files without using any other online storage service. I needed to have the files on the same server. Now, after 4 months, I'm completely satisfied with my decision and not just because of the local storage:
  • I deploy my application in 5 minutes with a single command
  • great documentation and support
  • awesome tools for managing my "remote" machine - rch client tools
  • no surprises, what I deploy is what I see with no sudden downtimes, errors etc
  • there's a free plan with 3 gears :)
So, let's start. 

We are going to use git so if you don't have it yet, install it now.

Create an account to OpenShift for free here.

We will install the client tools (rhc). From the command line:
gem install rhc
and we are going to configure them with:
rhc setup
Follow the instructions and type your credentials:
Choose to generate the token so that you don't have to login each time you interact with your remote machine (from now on we will call this gear):
If you don't have any SSH keys, OpenShift will automatically generate one for you (nice) and will ask you if you want it to upload it to the server so that you can access your code. Say yes.
Next, you will be asked to create a domain under which your applications will be grouped. Choose one (this is going to be used in your applications public url ex: todo-yourdomain.rhcloud.com). I chose arubystory:
That's all. We configured the tools to use our account.


OpenShifting the ToDo

Time to "create" the ToDo application on OpenShift. When we will fire the command, the tool is going to create the application on OpenShift and then it will try to clone the remote repo to a local folder with the same name as the application. We want to skip the last part because we already have this folder. To do so, we are going to execute the command from the directory containing our project's directory.
My todo project is under
/Users/developer/development/projects/todo
so I will execute it from
/Users/developer/development/projects
Doing so, the git clone will fail and we will have to manually connect our local repo with the remote later.

From the command line:
cd /to/the/directory/containing/the/todo/directory
rhc create-app todo ruby-1.9

Great. Now, let's initialize our local git repo. From the command line:
cd todo
git init
We will add the remote git using the information provided with the following command:
rhc app-show todo
Copy the value of the Git URL because you are going to use it in the following command:
git remote add openshift [paste the value here]
Let's commit. From the command line:
git add .
git commit -m "First commit"
And let's merge the remote:
git pull openshift master
As you can see, we have a conflict in config.ru. Edit this file and change it to the following (we overwrite the remote changes with ours):
# This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment',  __FILE__)
run Rails.application
Commit the changes, from the command line:
git add config.ru
git commit -m "OpenShift merge"
And time to deploy the application! With one line. This:
git push openshift master
Visit the application url from your browser:
http://todo-yourdomainhere.rhcloud.com
Don't worry, we expected this. We haven't setup the database for production. We will do this "sshing" to our gear. From the command line:
rhc ssh todo
Yes, this is your gear. Let's setup the database. From the gears command line:
cd app-root/repo
RAILS_ENV=production rake db:setup
Exit the gear:
exit
and from your command line (not the gear's one) restart the application:
rhc app-stop todo
rhc app-start todo
Give it some time and refresh your browser. There it is!
Now, if you try to sign up you'll see the error message again. This is expected too. Our email configuration was only for the development environment (we had it only in development.rb file and also we were using the mailcatcher for simulating an smtp server). We obviously want emails to be really sent to our users in production so we must go with a real configuration. I will show you how to configure mailer to use a gmail account. Add the following in config/environments/production.rb
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.default_url_options = { host: 'http://todo-yourdomainhere.rhcloud.com' }
  config.action_mailer.asset_host = 'http://todo-yourdomainhere.rhcloud.com'
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address: 'smtp.gmail.com',
    port: 587,
    user_name: 'your_username@gmail.com',
    password: 'your_password',
    authentication: 'plain',
    enable_starttls_auto: true
  }
Let's deploy the fix. From the command line:
git add .
git commit -m "Mail setup in production"
git push openshift master
After the gear starts, refreshing the browser you'll see the error message again. This time the problem is once again the database. But why? Take a look at your db/database.yml
As you can see, the database is saved under db/production.sqlite3. This file doesn't exist in our repo and each time we push to the openshift remote we actually delete the remote created database. How are we going to fix this? We are going to set this value pointing to a file that is not in the repo but to another directory of the gear! That directory already exists and OpenShift has taken care so that we can see what it is with an env variable: OPENSHIFT_DATA_DIR . Change the production database line to this:
database: <%=ENV['OPENSHIFT_DATA_DIR']%>/production.sqlite3

Once again:
git add .
git commit -m "Production database fix"
git push openshift master
Ssh to the gear again and re-setup the database:
rhc ssh todo
From the gear's command prompt:
cd app-root/repo
RAILS_ENV=production rake db:setup
Let's see that the database was created (gear's command line).
cd $OPENSHIFT_DATA_DIR
ls
You should see the production.sqlite3 file there.

That's it. We're done! The application is successfully deployed to OpenShift.
Post a Comment