Proper continuous integration and continuous deployment with Git and Heroku - ruby-on-rails

I am developing a ruby on rails website using heroku and git.
What tools and features should I use to set up the following simple development process?
CODE > CHECK-IN > AUTO TEST > AUTO DEPLOY
I check my code into my repository (preferred option, hosted git like github)
Tests are automatically run AND website is deployed in my staging heroku app
If tests pass, the website is automatically deployed on my production heroku app
If tests fail, I want to be notified somehow.
How would you do this?

CircleCi offers exactly what you need. We'll run your tests on every push, deploy them if they pass (to Heroku or using Capistrano/Fabric/anything really), and send you notifications if they fail.

to preface I am one of the founders of Codeship (https://codeship.io), which is a service that supports exactly this.
But more on topic, basically there are 2 different ways I think this could be implemented (please keep in mind that all branch names I use are arbitrary and can be named totally different):
staging/production in one go
Whenever you push to your master or a specific deploy branch you run your tests and if all of them pass you first deploy to your staging app, run separate tests (Selenium or sauce labs is great for that) and if that works out including migrations you push to your production app.
This is great as the latest version is always available in production and we use this cycle for a long time now. Works great for us. The downside is that pushing to a staging heroku app takes some time. If you want to run the migrations against a copy of your production data this takes even more time. It's not an eternity, but it takes a couple of minutes.
staging/production as separate steps
You could have separate staging/production branches which are deployed to the respective heroku applications. This has the advantage of being faster and you can control when to release certain parts. Especially for applications where you want external feedback before deploying to production this works great.
We support all of that at Railsonfire, but we are currently working on a new version of our service which is way better. We integrate really well with Heroku so you don't have to think about that (but still have the option to do it yourself in any way you want)

We use Integrity. It is a pretty simple solution - it won't do everything under the sun, but it's quite easy to set up and handles the most common use cases/features. It's also pretty easy to hack on, if you want it to do more.
Integrity states:
Heroku is the easiest and fastest way to deploy Integrity.
However:
NOTE
It isn’t possible to access repositories over SSH on Heroku
This is because your Integrity app will need an SSH key. It's not impossible, but definitely a few hoops to jump through. You'll need to give Integrity a private key and put it in the app, and then hack Integrity to use that ssh key when it initiates the git clone.
Of the things you listed, the automatic deploy is probably the thing most people would not expect their CI server to do (and Integrity does not provide out of the box). You'll need to configure git to use that ssh key and initiate a git push from the proper location (the checked out repository).
Unfortunately I don't know the details of how to do this--we actually run Integrity on a VPS.

There are many tools in the market that do this. SnapCI offers deployment pipelines that let you push every commit through tests and then subsequently into staging and production as different stages of a deployment pipeline. We also have full support for test parallelization, building branches and pull-requests.

Well, there is Hudson which provides a git plugin as well as scripting support. The rest is configuration, I would guess.
Hudson: http://hudson.dev.java.net

Try Heroku-Bartender. A write-up here.

Related

Public testing environment for RoR + Angular

currently I need a little hint for test running a RoR + Angular Application. And with test running I talk about that the "project owner" can see the current version of the project. For large projects with a lot of developers we had a build server, where the server got the current version from the git repository and deployed it as a "nightly build".
For projects where I'm the only developer I use dropbox to synchronize my working directory to a server, that is accessible for the project owner.
But now I'm working on a small project with 2 other developers. The build server is too much and the dropbox solution, well it's not going to work, because every one of us has a different state. And working on the same Dropbox directory is a no go.
So what's the best solution?
Consider running it on Heroku, which has a free tier. Once set up properly, deployments can be done by simply pushing to your Heroku git remote, or you can set it up to watch an existing remote repository branch (such as a particular branch on Github).
Or you could run it on your own machine. If you are behind a firewall you could set up a tunnel so your team can see it, with something like ngrok.

deploying a rails project to a remote server

is it possible to deploy a rails project to a remote server using FileZilla ? the server is running nginx/1.4.6 (ubuntu)
if no what is the best way to deploy the project if there is already a running version !
To answer your question yes, the code needs to be up, so FTP should do the trick. You might need to restart nginx to pick up the changes, usually touching a restart.txt is enough, but that's particular to your setup.
Is this the best way? Possibly not!
Others suggested capistrano and that would be a good fit for a server you maintain, or go Heroku (or similar) service for a simpler setup.
Deploying a Rails app is a tough job. There is always the easy way (heroku) however shared servers don't deal well with rails. Theoretically you can but usually this shared servers have really outdated ruby and rails versions and are absolutely useless. And you can try to connect via ssh and try to update it but i doubt you will be able to do that. So... If you are a rails developer i can suggest.
1- For small apps run Heroku (easy and free) however cost grows like hell with the app's growth
2- If you're thinking about developing big apps get a dedicated server (you can get cheap ones for 5€/month) and configure it as u would for your computer except when you run rails you run it in production.
3- Trust me... i fought enough Rails and shared servers and i quit... I just gave up

Deploying on Heroku with Capistrano?

I'm still getting used to the Rails development ecosystem. Recently I learned how to use capistrano for deploying to my servers using apache and passenger, and I love how I can put a rather complex set of deployment instructions into my deploy.rb so that they are executed with a single "cap deploy" call, with an automatic rollback if anything goes wrong.
Now I'm looking into deploying my project on Heroku, and I expected to be able to use capistrano for my deployments there. But I've been unable to find any documentation on how to do this. Is it possible? Are there capistrano tasks that let me automate deployments on Heroku?
Does this even make sense? After all capistrano works in a specific way (ssh into the server) and assumes a specific directory structure (public/releases/shared etc). Both of these are not possible with Heroku as far as I know. But still I would like to have the convenience of capistrano. I know I can put the steps necessary for my deployment (git push/migrate/restart resque workers...) into a single rake task, and I would have the convenience of deploying with a call to a single command; but I would not have the benefit of capistrano transactions and rollbacks, which are very important in my mind.
I'm probably missing something very basic about how these technologies fit together. It surprises me a bit I haven't been able to find any discussion on this subject anywhere. Can anyone share their experiences?
Heroku uses Git for deployment, and is not capistrano friendly. In fact, the philosophy itself is different - Heroku does not have 'servers' where you can SSH to, or customize server to your need.
Heroku uses Dynos, which are predefined instances, with specific deployment architecture which covers majority of Rails deployment needs. You can do actions like Rollbacks, backups, migrations etc with Heroku, in some cases, more sophisticated than normal capistrano scripts.
Unless your setup is quite different, you can safely use Heroku for Rails (with only Git, of course) . If not, AWS is better bet.

Using GIT in production Rails machines

Should my production Rails project use GIT? it will be easy for me to update the
servers and to push hot fixes, but what if I'll have a conflict during a pull?
and if I'll accidentally pull something wrong it make cause some downtime.
What is your advice on how to synch between the GIT repository & production?
Thanks
How about using a dedicated deployment system like Capistrano? It solves many of the issues you are trying to avoid.
Don't leave local changes on your production machines, and there is no risk of conflicts.
Production installs should pull from a dedicated branch/tag (e.g. use gitflow, production machines pull from the latest tag or simply master) - not the branch you regularly push to (develop, if you use git-flow).

Why is it supposedly "hard" to deploy Ruby on Rails to production?

I admit that I don't follow much of anything "right" on deploying test versus production code. I have been using ASP.NET, and I typically run it locally in Visual Studio, it works, I upload it, I test it again on the production server.
I have read several people say that deploying Rails apps is harder and there are special programs/ways on the ruby site about deploying RoR. I've only toyed with RoR. What is special about deployment? You don't just copy and paste the code and run it (from development machine to the production)? Is it because one is in Apache and the other running on the built in server?
This will be on a Mac Server if it matters.
Deploying RoR is not difficult anymore, especially with Phusion Passenger.
What is somewhat difficult, is getting a automated production environment setup with capistrano, vlad, etc. If you don't mind simply copying your code to the server, you can do that just fine. Most people choose not to do it that way because you lose out on a lot of the benefits that the automated deployment tools give you.
I guess people consider a Rails app harder to deploy than say some PHP apps or such where you just plop the code somewhere and point Apache or whatever at it. But, as mentioned above, you could do that now with Phusion Passenger.
We use Nginx+Passenger, but not for simplicity of deployment. Capistrano is our deploy tool of choice, and really, unless you have a very simple app, you're going to want something like Capistrano anyway. For example, with our deploy, we do a slew of things:
run any database migrations
generate release notes automatically, based on all the commits to Git between the last deploy and this one
notify various people via email (with differing lists depending on whether the deploy is to our staging environment or production) - we do this via cap_gun which integrates with Capistrano.
Notify New Relic RPM of the deploy so it can mark it in our RPM analysis
Notify Hoptoad of the deploy, so it too can have that data when reporting any exceptions
produce our sitemap.xml file, and ping Google to tell them there's a new one
update crontab files (I store our crontab files for each server in our git repo, and then on deploy it sees if there is a new version and updates accordingly, etc.).
flush/restart memcached
There are other ways aside from Capistrano, but it's a proven tool, with a lot of flexibility, yet pretty simple to setup a vanilla configuration.
So, my take is that once you get into any app that is beyond just the very simplest of apps, you're going to need/want to be doing things other than just simply updating the code. In the beginning though, if you just need the code updates, and maybe Rails migrations, then you can do simpler things like Passenger and code sync, or look at tools like Heroku or Engine Yard's stuff where they do a deploy by doing a Git clone (and then offer some additional abilities).
Another super easy way to deploy is with http://heroku.com/
Some of the issues you face with deploying rails to production:
Database connection.
You need to be sure that the database connector is set up for the production environment.
Database migrations.
You have to run database migrations against the production database even though you may have already run them in production/testing/staging
Ruby version. The version or sub-version or Ruby can trip you up, e.g. An error occurred while installing debugger-linecache (1.1.1), and Bundler cannot continue
Gem dependency.
Your production environment may have different packages and gems from development. Bundler will figure this out for the most part and install the dependencies but occasionally there are still issues that you have to resolve manually.
Dependencies.
Some gems on some machine have particular dependencies. I have seen frequent problems with using gems on my unix box that work on OSX and vice-versa.
Note the last 3 shouldn't affect you if on the same machine but I included them based on the title and to be comprehensive.
It's not especially hard. If you stick to conventions then with a little bit of configuration it boils down to this:
cap deploy
...however there is sometimes a bit of effort needed up front to get the workflow in place.
The good news is that lots of people have packaged up solutions and stacks for RoR that you can just plug and play. For example, google ec2onrails - this is a packaged Ubuntu image and set of capistrano tasks for running rails apps in Amazon's EC2 cloud, with lots of common stuff set up already out of the box.
Choose a good hosting provider and you should be able to find something similar for that also.
An easy way to deploy Rails apps is to use Phusion Passenger. Deployment doesn't get much easier than that for any programming language or framework. You can do that on a Mac server.
Another really easy way to deploy rails is with jruby and the glassfish gem.

Resources