Put Your App Online With OpenShift

Created by Katie Miller, @codemiller

Get OpenShift

OpenShift is a cloud computing Platform as a Service (PaaS) that makes it easy to deploy apps online. It is open source and written in Ruby.

To get started create an OpenShift Online account, which allows you to put three apps online for free. Once you are signed up, install the OpenShift RHC Client Tools by running these commands in a terminal and following the prompts:

gem install rhc
rhc setup

The above instructions assume you installed Ruby using RVM or RailsInstaller. If you used another approach, there is more info about installing RHC for different set-ups in this guide (you may need to do sudo gem install rhc).

COACH: Talk about the benefits of deploying to a PaaS such as OpenShift, as opposed to traditional servers. Discuss SSH and why we need to upload a public key to communicate securely.

Preparing your app

Create OpenShift application

We are going to create an OpenShift Ruby application with a PostgreSQL database, using a sample OpenShift Rails application as our starting point. Before we do that, in your terminal change to the parent directory of the one containing your railsgirls code, probably called projects. The cd command below will take you there if you are currently in your railsgirls directory; if not, substitute another cd command.

cd ..
pwd

The output from the pwd or ‘present working directory’ command should show you are now in the projects directory (or whatever your parent directory was called). To create the OpenShift app in the cloud and make a local copy of its contents, run the following command in your terminal.

NB: This command is for those using Ruby 2.x and Rails 4. If you have installed Ruby 1.9.x, replace ruby-2.0 in the command with ruby-1.9. For Rails 3, change the --from-code URL to https://github.com/openshift/rails-example.git.

rhc app create openshiftapp ruby-2.0 postgresql-9.2 --from-code=https://github.com/openshift/rails4-example.git

If you see a message like Are you sure you want to continue connecting (yes/no)?, type yes and press enter.

The terminal output should include a URL; open a browser window and go to the application URL to view the sample Rails application (the URL will have the form http://openshiftapp-yourdomain.rhcloud.com).

COACH: Explain what Git is and why we use version control systems.

Add version control

We now have a sample app running in the cloud, but we actually need only a few pieces from its codebase. Before we copy across the bits we need, we should put our Rails Girls app under version control with Git.

Change back to your railsgirls app directory and initialize it as a Git repository with the following commands:

cd railsgirls
git init

We don’t want the pictures uploaded during app development to be part of our repository, so run the following command to instruct Git to ignore them:

echo "public/uploads" >> .gitignore

Add and commit all your app files to the Git repository with the following commands:

git add --all
git commit -m "First commit of Ideas app"

COACH: Explain the Git commands used and .gitignore.

Copy sample app code

We need the .openshift directory and config/database.yml file from the sample application for our Rails app to run on OpenShift. Copy these from the openshiftapp directory to the railsgirls directory. You can use Windows Explorer or another graphical file system tool to do this if you like, or alternatively run the following commands from the railsgirls directory in your terminal:

cp -r ../openshiftapp/.openshift .
cp ../openshiftapp/config/database.yml config
xcopy /e /i ..\openshiftapp\.openshift .openshift
xcopy /y ..\openshiftapp\config\database.yml config

Check that the copying has worked by looking in the railsgirls app directory. There should now be a subdirectory called .openshift. Open the file config/database.yml; it should now contain OpenShift environment variables such as OPENSHIFT_APP_NAME. If your database.yml file does not contain variables like this, try opening .openshift/config/database.yml or openshiftapp/config/database.yml in your editor and copying across the contents of the file.

Add and commit the new and changed files in Git with the below commands.

git add --all
git commit -m "Added OpenShift config"

Change database

The next step is to change our Rails Girls app database from SQLite to PostgreSQL. Open your application’s Gemfile and replace:

gem 'sqlite3'

with

gem 'sqlite3', :group => [:development, :test]
gem 'pg', :group => [:production]

Do a bundle to set up your dependencies:

bundle install --without production

On some platforms, this may generate platform-specific versions of your Gems that cause issues when you push your app to the cloud. To prevent this, open your Gemfile.lock file and check the versions of the ‘sqlite3’ and ‘pg’ Gems. If they have a platform-specific suffix, such as -x86-mingw32, remove this (eg. change pg (0.16.0-x86-mingw32) to pg (0.16.0) and sqlite3 (1.3.8-x86-mingw32) to sqlite3 (1.3.8)). Save and close the file, and run the above bundle command again before continuing.

Add and commit your changes in Git:

git add --all
git commit -m "Changed production database to PostgreSQL"

COACH: Talk about relational databases and the differences between SQLite and PostgreSQL.

Deploy app to OpenShift

We are now ready to deploy the Rails Girls app to OpenShift. We need to tell our Git repository where to push the code. To get the location of your OpenShift code repository, run the following command, and copy the Git URL from the output.

rhc app show openshiftapp

Now run the following commands, replacing the SSH string with your Git URL. We are using ‘-f’ for force here because we are happy to wipe away the history of the current OpenShift repository, which contains the sample Rails app. When you are pushing future changes, you can just use ‘git push’.

git remote add openshift ssh://0123456789abcdef01234567@openshiftapp-yourdomain.rhcloud.com/~/git/openshiftapp.git/
git push -f --set-upstream openshift master

Refresh the app in your browser to see the result.

COACH: Talk about Git remotes.

Extra credit

Congratulations - your Rails application is now online for the whole world to admire. The following sections explain optional further steps you can take to improve and share your app.

Persist uploaded images

The app should be looking pretty good now, but there is an issue lurking because of the ephemeral nature of the deployment. When we push a new version of the application, anything stored within OpenShift’s copy of the repo will be wiped to make way for the new files. This includes the images uploaded by users. To fix this, we can store these files in a persistent directory on OpenShift instead. The filepath of the location we need is stored in an environment variable.

COACH: Explain the motivation for using environment variables.

The directory where uploaded pictures are currently stored is within the app repository, so it will be deleted when we rebuild. To switch the uploads directory to one that will persist, open app/uploaders/picture_uploader.rb and replace

def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end

with

def store_dir
prefix = ENV['OPENSHIFT_DATA_DIR'] ? "#{ENV['OPENSHIFT_DATA_DIR']}/" : ""
"#{prefix}uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end

def url
return "/uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}/#{File.basename(file.path)}" if ENV['OPENSHIFT_DATA_DIR'] && file
super
end

Now uploaded images will be stored in a persistent directory, but they will still be available through the same URL as what we were using previously. To make this work, we also need to add a symbolic link on the filesystem from the repository location to the real storage location. To do this, open .openshift/action_hooks/build and add the following code:

mkdir -p $OPENSHIFT_DATA_DIR/uploads
ln -sf $OPENSHIFT_DATA_DIR/uploads $OPENSHIFT_REPO_DIR/public/uploads

This action hook code will run every time the OpenShift app is built, so the link between the directories will always be there when it’s needed.

Commit your changes and push them to the cloud:

git add --all
git commit -m "Added OpenShift environment variables"
git push

The images you uploaded before making this change will no longer display, but anything uploaded now will stick around between app rebuilds.

COACH: Explain symbolic links.

Push code to GitHub

Now that your application is under source control with Git, you may also wish to share a copy with others on a Git repository website such as GitHub. To push your code to a GitHub repository, create a repository on GitHub and copy the HTTPS string (something like https://github.com/username/reponame.git).

Navigate to your OpenShift app repository in the terminal and enter the following commands, replacing the HTTPS location with the string you copied:

git remote add github https://github.com/username/reponame.git
git push github master

The ‘master’ branch of the local copy of your repository will be pushed to GitHub. Go to the GitHub website to check it out.

COACH: Talk about Git branches and the benefits of open source code.

Conclusion

Your Rails app is now running in the cloud on OpenShift. You can push whatever other changes you like and share the URL to show off your app to your friends.