Deploying an application to Cloud Foundry

March 3, 2014 Shatarupa Nandi

Want to deploy a Rails app to ‘the cloud?’ Here are 5 steps to get your app on Cloud Foundry. Although here I’ll deploy a JRuby on Rails app, deploying a Ruby on Rails app works just the same.

Step 0: Initialise Rails App

In this example, I’ll use postgres but Cloud Foundry supports MySQL and other popular databases too.

$ jruby -S rails new myApp -d postgresql

Step 1: Creating Orgs and Spaces

Login to your Cloud Foundry account. If this is your first time logging in, it asks you to create a new Org. Orgs and Spaces are Cloud Foundry jargon which seem confusing and superfluous initially. However, they are a neat way of managing environments. Having deployed to Cloud Foundry on a couple of projects now, here is what Orgs and Spaces mean to me:

  • Org – Use this to name a cluster of applications that are logically grouped together.
  • Space – Use each space as a separate environment for your application. An Org has multiple spaces, which serves as a convenient way to manage different environments for your applications.
    My Cloud Foundry account has an Org called all-apps with a space called staging.

    Step 2: Logging into Cloud Foundry from the console

    cf v6 is a more performant Go rewrite of the ruby gem cf. Get cf v6 from here.
    Login to cloud foundry from the console using:

    $ cf login

    When prompted for an API endpoint enter api.run.pivotal.io. If all goes well, you should see a success message like:

    API endpoint: https://api.run.pivotal.io (API version: 2.0.0)
    User: <your_cloud_foundry_username>
    Org: all-apps
    Space: staging
    

    Step 3: Prepping for deploy

    Cloud Foundry is not tightly coupled with your version control system. While this can be a little extra work and doesn’t give you the benefit of automatically deploying every time you push to git, I’ve generally found it to be quite useful:

  • I don’t have to worry about taking staging/demo instances down or the PM/customer stumbling upon an unfinished feature every time I push my changes to git. In general, since everything that gets pushed to git doesn’t get immediately deployed I find it encourages developers to push more often.
  • Another advantage is having a .cfignore separate from .gitignore. This was helpful so I could upload API keys/credentials/anything-I-don’t-want-to-be-version-controlled only to Cloud Foundry. Similarly, by ignoring logs/, tests/, dev-tools/ only in .cfignore, uploading the app to CF is a much faster process.
  • Finally, I often found myself making commits to git to tweak configuration or credentials to make my app work on Heroku. Deploying from my working directory allows me to directly applying these changes without necessarily checking them in to git.
  • Here’s a sample .cfignore for myApp:
    tmp/
    log/
    test/
    .DS_Store
    

    Step 4: Creating and binding to services

    $ cf create-service elephantsql turtle elephantsql-myApp-staging

    This creates an instance of the ElephantSQL service that may be used by any app in the staging space. If you are unsure of what services you want to use cf marketplace lists all available services and plans. To bind to the service instance(s) that you have created, use the manifest.yml. An app manifest is a way to specify details about your application. While its not required to deploy, its an easy way to configure your app. A simple manifest.yml looks like:

    applications:
    - name: myApp-staging
      memory: 1024M
      instances: 1
      host: myApp-staging
      domain: cfapps.io
      path: ./tmp/deploy
      timeout: 120
      command: bundle exec rake db:migrate && bundle exec rails s -p $PORT
      services:
      - elephantsql-myApp-staging
    

    While most of it is standard, a few interesting things are the path, command and timeout. path represents the path from which the manifest deploys. Copying the contents of your working directory over to a ./tmp/deploy and pointing your manifest to deploy from there allows you to continue working while the app deploys. command is what cloud foundry runs to start your app. timeout is a way to tell cloud foundry about your app’s startup time. If you don’t specify a timeout, Cloud Foundry assumes a default of 1 minute. This is reasonable for most RoR apps, but JRuby needs a longer startup time.

    Step 5: Deploying

    The last thing you need to do is to allow your Rails app to serve static assets in production. In production.rb make sure you have an entry config.serve_static_assets = true
    myApp is now ready for deploying!

    $ cf push myApp-staging

    Cloud Foundry uses Heroku’s Ruby buildpack, which precompiles assets for your Rails apps and if you have a single app it is faster to precompile assets on Cloud Foundry rather than uploading precompiled assets. However, if you are pushing multiple apps, it is faster for you to precompile assets locally once and upload them.
    To do so, $ RAILS_ENV=production rake assets:precompile before pushing your app.

    Do you see your robots.txt when you go to myapp-staging.cfapps.io? Success! :)

    PS: At any point if you get unexpected results, some useful debugging commands are:
    cf logs myApp, cf apps or cf to list all cf commands.

About the Author

Biography

Previous
Adventures in Clojure: TDD
Adventures in Clojure: TDD

Getting started with Clojure Several months ago, I had picked up a copy of Seven Languages in Seven Weeks a...

Next
Rails to iOS: What the *&@#^ are these symbols in my code?
Rails to iOS: What the *&@#^ are these symbols in my code?

For many developers with a background in Ruby or Python (or other similarly human-readable languages), the ...

×

Subscribe to our Newsletter

!
Thank you!
Error - something went wrong!