This post was sponsored by Ninefold. Thank you for supporting the sponsors who make SitePoint possible!
I can remember back in the day, nine-ish years ago, when deployment was a manual process. Sometimes, in took 99 minutes to deploy even the simplest of sites. On the Tedium and Frustration Scale, deployment was a solid ‘9’.
Thankfully, those days are behind us. With Continuous Integration having grown into a common, nay expected, practice, how could things get better? The answer? Continuous Deployment. Now, let’s get our terms straight, because there are about 999 ways that Continuous Deployment can be defined, so I’ll pick the one I like.
Continuous Deployment is the practice of automatically deploying every code change that passes automated tests to production.
This is not the same as Continuous Delivery, where you automatically deliver code changes to a staging environment where rigorous integration testing ensues. Continuous Deployment (CDep for the rest of this article) means, you make a change, push it to the main repository, the tests run AND pass, and the code is deployed to production. BOOM! (Incidentally, this post and I agree on these definitions.)
CDep is not for the weak or weakly test-covered. Those who dare attempt CDep have great confidence that the automated tests cover all the functionality of the application. This is no small feat. I would say 99.999% of projects probably don’t have the test coverage to pull off CDep. But for those that make the effort and have the discipline, their rewards are great: Confidence that changes won’t cause regressions and that you won’t be losing time doing manual deployments. The fruits of CDep labor are the sweetest on the vine.
The growing ubiquity of CDep is directly attributable to the rise of the Platforms-as-a-Service (PaaS). There are many PaaS, and today we’re going to check out Ninefold.
Ninefold is a PaaS that specializes in hosting Rails applications. Alongside the ease of deployment that comes with most PaaS offerings, Ninefold also offers numerous plugins for things like Redis, PostgreSQL, SendGrid, New Relic, Memcached, and others. A critical differentiator for Ninefold is the ability to add raw Virtual Servers. If there isn’t a plugin for a piece of software you want to leverage, simply spin up a VM and host it yourself.
My demonstration today will show you how to use Ninefold and Codeship to easily create a CDep workflow for a Rails application.
Our application is a simple Rails app that services the critical needs of those who desire to list things that come in multiples of 9. Users can add a thing and its nine-multiple to the growing list of NineThings. This is THE /insert current big-time social app here/-killer. Here’s what it looks like:
Isn’t it beautiful? I am not going into detail about how it’s setup, simply because it is a just-use-the-generator Rails app with the
foundation-rails gem added to make it a bit cleaner. The
NineThings model-view-controller sequence was generated using the
scaffold generator. Oh, and I am using PostgreSQL. Nothing special in this setup.
The source is in this Github repository, which is what I will use when registering the application with Ninefold. Feel free to fork the app (or pick your own Rails app) and follow along.
Signing Up for Ninefold
Close the welcome screen and click on “Deploy New App”. The first piece of information Ninefold requires is the location of your source code repository. In my case, it’s the Github repository I mentioned previously. So, I click on “Sign in with Github”, approve what Ninefold wants to do, and a list of my Github organizations and repositories show up on the dashboard. That’s cool.
After selecting the repository and branch for Ninefold to watch, you need to decide if you want Ninefold to deploy on every push to the selected branch. Let’s say ‘Yes’ for now and move on to the next step and setup our deployment environment.
Ninefold offers various infrastructure options based on the scalability needs of your application. For this application, I am just testing things out and want to keep it cheap/free. I can do that using the 1.5GB option for the web server, the smallest PostgreSQL database, and saying ‘No’ to background workers (though Ninefold does not charge for those). That shows a monthly cost of $46.91, and Ninefold will waive the first $50 of my bill under a current promotion, so perfect. Next step. please.
The last details consist of the desired Ruby version, application name, plugins, and any custom deployment plans to run. My app isn’t going to use any of these, so I excitedly click “Deploy”.
It takes a few minutes to deploy, so this is a good time to introduce Brutus, Ninefold’s shaven yak. Brutus comes with the Ninefold CLI, which can be installed with the ninefold gem (
gem install ninefold or add it to your Gemfile and
bundle). Open up a terminal, go to your Rails app project directory, and install the gem.
The CLI is based around a
ninefold command, sensibly. Typing
ninefold gives you an idea of the available options:
The first thing to do is sign in. Type
ninefold signin and enter your Ninefold user information. Brutus will run off and sign you in. Once signed in, the CLI allows you to interact with your Ninefold applications using the
ninefold app command.
ninefold app list lists my single ninethings application. (BTW: There are also
ninefold brutus commands where you can make our favorite yak chew and say stuff. Try it, it’s fun.)
I won’t go over all the CLI commands, as they are pretty self-explanatory. The one I will highlight is
ninefold app redeploy_command, which lists the CLI command to redeploy your application. In my case:
AUTH_TOKEN=<my auth token> APP_ID=10906 ninefold app redeploy --robot --sure
This command is important because it’s the easiest way to get your auth token and application id, which is needed (in some cases) if you want to redeploy the app outside of the Ninefold dashboard. I will not be using that command today, but if you’re on Ninefold, it’s good to know.
OK, by now, your Ninefold app should be deployed. The Ninefold application dashboard looks like:
The “Overview” tab has all the information you would expect: application name, URL, repository, branch, etc. The “Deployment URL” is something we’ll use later to get our CDep on. Notice the “Automatically redeploy my app when I push updates to my code” checkbox is enabled.
The “Configuration” tab allows for environment variables, custom deploy commands, and plugin configuration. The remaining tabs are self-explanatory, so you can explore those on your own.
Go back to the “Overview” tab an click on the “Domains” link. Your app will open up and you can add/see all the NineThings. We’re on the internets. Let’s push a trivial change.
A trivial change to our layout. Commit the change and push it to your Github repo, making sure that you are using the
master branch. Go back to the Ninefold application dashboard and wait a few seconds. The following notification will pop-up in the lower-left hand corner:
Excellent. Right now, we are in the realm of Continuous Delivery (if we had good tests). We want more, we want Continuous Deployment. This is where CodeShip comes in.
Codeship is a company that offers Continuous Integration and Delivery (and, today, Deployment) as a service. We’ve written about Codeship before, but in a nutshell, Codeship will watch your source code repository for changes, running your tests for each change. With a bit of configuration, Codeship can also notify you of failures/successes, run just about any command, and/or deploy your code. That last one is our focus today.
Go ahead and sign up for a Codeship account. When you first sign up, Codeship onboards you with a wizard to create your first project.
You’ll be prompted to pick your source code provider, either Github or Bitbucket. It’ll then connect to that provider (with your approval, of course) and list your repositories. Pick the ninethings repo.
At that point, you need to specify your setup and test commands:
Setup commands run to get your project to the point where the tests are ready to go. Test commands run your tests. In our case, we install the Ruby version of our choice, bundle, set the RAILS_ENV, and load the schema. Codeship had this all setup by default, but you can change or add whatever you need.
Once you’re through the wizard, you’ll land on the project page. At the top of the page, Codeship has some suggestions on what to do next:
Well, lookie there! It’s like they read our mind. The first button is “Set up Continuous Deployment”. I say we click on it.
Codeship offers many options to deploy after a successful build. Ninefold isn’t on one of those buttons, but that is because there are 9,999 ways to redeploy your application on Ninefold. It may be the easiest service to integrate with in the nine galaxies.
Straight from the Codeship blog, setting up deployment to Ninefold is easy as:
- Clicking the “$script” button
- Enter your Ninefold “Deployment URL”
Where do you get the Deployment URL? The savvy reader remembers it was on the Ninefold application dashboard “Overview” page:
There it is. Also, be sure to uncheck the “Automatically deploy” check box. Otherwise, Ninefold will deploy your app on every push, regardless of passing tests.
Ok, return to the Codeship.io project page and paste in that Deployment URL.
Save the step, and we’re done. Really.
CDep in the House
If you don’t believe me, I’ll prove it. Let’s make another noticeable change to our app:
Now, introduce a test failure into the app, like so:
# test/models/nine_thing_test.rb class NineThingTest < ActiveSupport::TestCase test "the truth" do assert false end end
rake in your local app directory will show the failure. Commit and push that change to your GitHub repository. If you’re watching the Codeship.io project page for your project, a build will kick off, like so:
As you can see, it failed. If you reload the Ninefold hosted app, our
h3 is not there.
For this next bit, open up two browser windows: one on the Codeship project page and one on the Ninefold app dashboard. Fix the test (change
true), commit, and push.
Codeship runs the build, runs the test, the tests pass, and it deploys to Ninefold. Ninefold then redeploys the app. I told you we were done. On a scale of 1 to 9, I give this whole process a 9+!
Reloading the Ninefold application URL will show our change is deployed:
Voila! We are going to party like it’s 1999.
Continuous Deployment is the holy grail of making developers lives easier. It gives you a chance to focus on the code, while Ninefold focuses on infrastructure and Codeship focuses on deployment. Hopefully, you’re inspired to get this into your workflow. I guarantee 9X more free time!