BEN DIXON: OK. So, I'm Ben. I'm a Rails developer and the author of a book called Reliably Deploying Rails Applications. I spend a lot of people - a lot of people? A lot of time teaching people Ruby at MakeItWithCode dot com, which is an online mentor-driven class for people who are new to Ruby but want to get started making things quickly. I spend the rest of my time working with the awesome guys at HelloSwimio, where we make cool tech for swimmers. So we make things like the time tabling system for the Olympic pool in London, the speedo swim tracking app, and the first automatic lap tracker for the Pebble smart watch. So, before we get started, could you put your hands up if you've deployed a Rails app of some sort to Heroku. Awesome. Now keep your hand up if you've deployed a Rails app to a server that you've set up yourself. Good. That's less people. So if someone came to me and said, I want to deploy my first Rails app, how should I do it? I wouldn't think about it, I'd just say use Heroku. And I'd say use Heroku, because Heroku makes deploying apps incredibly simple. You just commit your code, Heroku create, git push Heroku, and magically, a couple of minutes later, your application is live, on the internet, for the world to see. And because Heroku has made this process so simple and so easy, it's really easy to take that server stuff and kind of put it in a bucket of things we don't look at. Because it's complicated and Heroku makes it really easy, so why would we bother? And what I'd like to demonstrate in this talk is that, in the same way Rails makes building web applications really, really easy, there are lots of great tools out there that make setting up servers for them and deploying to those servers really easy. And once you get the hang of these tools, you can do some really cool stuff. Before we get started, two important bits of terminology, which probably you already know. A PaaS, a platform as a service, and by that I mean something like Heroku. So something that just abstracts all of your infrastructure away so that you don't have to worry about it. On the other scale, you've got a VPS, a Virtual Private Server, and for the purposes of this talk, I just mean some sort of Linux server running the cloud. So the type of thing you get from Linode or RackSpace or DigitalOcean. So, to get started, I want to take a little look at what's going on behind the scenes when you deploy a typical Rails application. How do we go from Rails S on our development machine to a Rails app on a VPS somewhere serving our application to the world? So, here we've got a beautiful picture that I've drawn, because I'm new to Keynote. And the black box around the outside is our VPS. It's a single VPS. And this is the first thing that seemed to surprise lots of people. For a simple production configuration, you only need one VPS. In the same way, in development, you can run your entire Rails application on your development machine. For simple production application, you can run everything on a single VPS. And that VPS will have three main components on it for almost all Rails applications. You're gonna have a web server, you're gonna have an app server, and you're gonna have a database server. So, when someone types in the address of our website, a request comes in. It hits our VPS, and the first place that request is gonna go is our web server. Now, if that request was for a static file, and by a static file, I basically mean, anything that goes in the Rails asset pipeline or anything that you might find in the public folder, the web server's gonna deal with that directly. It's gonna send that file straight back to the user for display in their browser and that's the end of it. If, however, that request is for a dynamic page, so for a page in our Rails app, essentially, that's gonna get passed back to an app server. Now, when we run Rails S in development, what we're starting is an instance of an app server. So, the app server here is Rails S running on our VPS. So the web server passes the request back. The app server generates the response and then passes it back to the web server, which then returns it to the user. And in development, we're probably used to the web, the app server being something like Thin or WebRick. In production it might also be Thin or Webrick. It might also be something a bit more advanced like Puma or Unicorn. Finally, for pretty much all Rails applications, we're gonna want some sort of database server. And that's probably gonna be PostGres or mySQL or Mongo. And, again, we don't need a separate database server. This all runs on our single VPS. So, to recap, a request comes in and it hits our web server. Probably EngineX or Apache. If it's for a static file, the web server deals with it. If it's for part of our Rails application, it gets passed back to the app server, which is basically Rails S, and the app server may communicate with the database server, read some data, write some data, and then the app server constructs the response, sends it back to the web server, which serves it to the user. So, you'd be forgiven for looking at that and thinking, well, that already looks more complicated than Heroku. Why on earth would you ever do that? Why not just use Heroku? Well, I started doing this, if I'm honest, because of cost. I had quite a lot of side projects, and as you probably already know, most past solutions charge by the process. And a lot of my personal projects and side projects had background jobs. Now when you've got five or six side projects, all of which would need two Heroku dynos, suddenly that bill at the end of the month starts to get quite substantial. And so I wanted to save money by deploying to my own servers. And I did. It's worth bearing in mind, if that's also your motivation, that, as with any new skill, you have to invert. Invert? You have to put in a certain amount of time to learn it. If you were to account for the time I put into learning this to begin with, at market rates, I'm fairly sure there would have been no saving at all. Personally, they're my own projects. I wasn't paying myself market rates. And I was happy to treat it as an investment which would pay off in the long term, and it has. Actually, it turned out, the biggest benefit of learning how to do this was nothing to do with money. It was the infrastructure went from being this kind of necessary evil that I have to have in order to run my Rails apps, to just another tool that I could use for building interesting stuff. And the best example of that, for me, is Make It With Code. We provide our students with a cloud IDE that has Ruby pre-installed. And that means they can hit the ground running. They can start writing Ruby code really quickly. And the techniques that we use setting those up automatically for all of our students are exactly the same techniques that I'm gonna cover in this presentation for setting up Rails apps. So it means that our infrastructure has gone from being this thing that we have to have in the background, as like a supporting thing, to something that actually adds value to our product in itself. It's a part of our product. So if you decide to give this a go, I really, really urge you not to do it even slightly like I did it originally. Because it was terrible. I started off by getting a VPS. That bit was good. That bit worked. I Googled, how do I set up a Rails VPS. I found all these great tutorials that said, type in this command, then that command, then edit this config file. And I found loads of things on StackOverflow that said, here's what to do when that goes wrong and that goes wrong. And eventually I had this working server. And it was great. And it broke a few times in the first few weeks. But we fixed that when it happened. And, by and large, it worked for quite awhile. And it worked until it didn't work, and when it didn't work, I was in France, on a holiday with my family, and it was a fairly rural bit of France, and we had, we had a wifi connection. But it was only one wifi connection for, basically, the village. And to access that, we, we could access it by sitting half in a wardrobe on the top floor of the house, which was nice. And, so one morning I woke up and I was sitting in the wardrobe with a coffee and checking my email, and I had a wonderful, a lovely email from my host to say, Dear Valued Customer, your server is dead, you need to make a new one, Lots of love, from your hosts. And I thought, good. Right. So I set up a little desk in this wardrobe and for the rest of the day, my family sat by a river. They drank wine, ate cheese, mocked me slightly, and I sat in a roof, in a wardrobe, in a heat wave, and pretty much followed the same tutorials I employed the first time. Made the same mistakes that I'd made the first time, and I got the server back up, but it really wasn't any easier the second time. And that seemed kind of wrong to me. That it seemed really frustrating. So I figured there must be a better way of doing this. If I'm honest, actually what I thought was, I can't believe there isn't already a better way of doing this, I should invent it and then I'll be rich and famous and everyone will love me. Luckily I took a step back and thought, OK, this probably already exists. And, of course, it did. And what I wanted was a configuration management tool. And a configuration management tool is really simple. It allows you to define and automate the commands that it takes to set up the server to do a particular thing. And what's amazing about a configuration management tool is once you've done it once, doing it again and again and again is completely trivial. So, that time you put in to start with, it will probably only be one command to set up an identical server the next time. And to give you an idea of just how simple it can be, I've got a brief demonstration of the process that I actually move, at the moment, on a pretty much weekly basis for setting up new servers. At the end of this presentation, I'll link to tutorials of how to do this yourself and the sample code. So please don't worry about following it step by step, I just want to give an idea about how simple it can be. So, here you can see, on the left, your left, there is a list of servers that I've deployed in the past. And I'm using my configuration management tool of choice, Chef Solo, which uses JSON files for defining what should go onto a particular type of server. And on the bottom you can see I've got a couple of web servers for Make It With Code, which at the moment is running a selection of Rails and Sinatra apps. And I want to write a new one. And to do this, I just create a new JSON file, web3 dot makeitwithcode dot com. I save it, and then this server, it's gonna be pretty much the same as web2. It's just running Rails apps. So I just copy all the JSON from my previous server, but it into the new one, and the bit I want to draw your attention to is, if you look at the bottom of that, you've got this run list with a list of things that are being called roles. And pretty much all configuration management systems have some sort of analogous concept to this, which, kind of individual components that you can mix and match to define what should go onto this server that you're setting up. So I've defined in the past, what goes on an internet server. What goes on a PostGres server. And now if I want that, I can just drop that role in, and I know that it will be set up in exactly the way that I want it. So on this server I want Redis. I didn't on the previous one. So I can just uncomment it. Uncomment it, yeah. And I'll get exactly the Redis configuration I want. The good bit, the fun bit, is once I've done this, I can type on command - knife solo bootstrap - and then the address of the, the VPS I've created. Presenter. And then leave it for about twenty minutes, go and get a coffee, and the output that will scroll through, it will tell me what commands it's applying. It will show me diffs of any configuration files that it's changing. And if it goes wrong, which it doesn't very often, it will tell me exactly what it was doing when it went wrong, so I can fix it. And at the end of this process, I will have a Rails server which is identical the last one I set up, and the one before that, and I can check that this works. I can fire up a web browser. I can go to web3 and the address that I gave it, and I'll get this wonderful Welcome to EngineX page, which says, that server is set up and it's ready to use. So, what I'm trying to demonstrate with that figure is that configuration management is basically, don't repeat yourself for setting up servers. If you think back to the first time you used, say, Devise, for example, the first time I used Devise, it took me ages to get all_auth and things like that working. And then, six months later, I came back to it, and didn't really remember any of the stuff that I'd done to get it to work. But I could go back to the code I wrote the first time, I could look at that code, copy bits of it, and it was much quicker. Now, the problem with just copying commands or entering commands manually when setting up the server is there is no natural audit trail of what did I do to make this work the first time. So there's a good chance, the second time you're gonna do it, you'll make the same mistakes as the first time. With a configuration management utility, you naturally create this audit trail as you go along. So that, in time, that time you invest up front, it goes much, much further in the long run. So, hopefully that's shown that the bit where people often trip up, getting a server setup, it doesn't need to be that difficult, and I'll give you the exact sample code at the end, which you can use if you want a head start. But something like Heroku, it doesn't just make setting up a server really easy. It makes deploying to one incredibly easy. Git push heroku. It pretty much couldn't be easier. And I think it's fair to say that the first time I used Heroku, it was completely revolutionary. So I came to Rails from Python/Jengo, and before that, PHP, and I'd used a whole range of, kind of, home grown deployment systems, which ranged from trying to remember what files you've changed and FTP them across to all sync things and custom shell scripts. And the one thing they all had in common was they were flaky and deployment was something you didn't want to do, because it would probably break. So you maybe deployed a couple of times a week. So I used Heroku for the first time and it was amazing. Suddenly I could apploy. Apploy? Deploy ten times a day. And it was just fitted into my normal workflow. So I was really keen that if I was deploying to my own servers, it had to be as simple as that. It had to be one command to deploy. And luckily, as is often the case in the Rails community, loads of very clever people wanted exactly the same thing, and so have developed some awesome tools, some awesome gems, to make it really simple to set that up. In the Rails community, I think the best known of these is probably Capistrano, which I'll talk about a bit more towards the end of the presentation. But, first, another brief demo of how simple it is to add Capistrano into an existing, in this case, Rails 4.1 application. Again, at the end, I'll give details of step by, a step by step tutorial and the ensemble code for doing this. So please don't worry about the individual steps. I just want to give an idea of what's involved. So, to get started, Rails 4.1 application. I just drop in the Capistrano gem and a few supporting helper gems. Save that, and then add it to git and, sorry, bundle and add it to Git. Under the hood we're still using Git to deploy in the same way Heroku does, so it's important to make sure changes like that are committed. And then running cap install, which just generates some basic configuration files. The first one of these is a cap file. This is just a rake file for capistrano. And here, I'm just telling it that I want to use those helper gems that I included in the first step. So I'm telling it that I want to use rbenv to manage what Ruby version I'm using. I want it to install gems for me, compile assets for me, and apply migrations. All the normal stuff you do when setting up a Rails app. We've then got our main config file, just deploy dot rb. And here I'm just giving the app a name, telling it which Git repository to deploy from, and getting rid of the load of the boilerplate for the simple application. I'm not gonna use it. Uncommenting out a few other bits of boilerplate. And then finally I'm gonna add an rbenv specific block that tells it to always use a particular Ruby version. I think, in this case, 2 point 1 point 1, when deploying this app. Finally, we have stage configuration files, so if you have a production server and a staging server, and here I'm just telling it that the production server is going to be web3 dot makeitwithcode dot com, which is the server we set up in the first demo. And then that should be made available to the public at, imaginatively, web3 dot makeitwithcode dot com. Then, firing up a console, running a command called setup config, and you can think of this like heroku create. This is just telling that server, or preparing that server for a new application. It's generating a few config files, it's creating a new database yml and telling EngineX that it needs to serve a new site. Then running another helper task that I added this time. Create database. This is just, create a new database on that server. Making sure there's a user that has permission to access that server. And this is the important command. Cap production deploy. And this, if we're using capistrano, is our equivalent to git push heroku. And if you look at the output, it's doing some pretty standard stuff. It's applying migrations, compiling assets and restarting the app server. And once that completes, we can fire up the web browser, visit it, and you can see we've got a simple, if utterly useless Rails application. And it has access to the database, it can read and write, and now we can iterate on that, and every time we want to make a change, we can just make that change, commit it, cap production deploy, and it really is as simple as deploying it to heroku. So one thing that we haven't looked at yet is, it's very easy to set this stuff up, but the other great thing about using a path like heroku is that when it breaks at 2 AM, it kind of isn't our problem. They have engineers and they get woken up at 2 AM. And they go and fix it. And our application just comes back up online again. And we can't get around that completely. It's now our problem when it breaks at 2 AM. But luckily there are lots of tools out there which mean we can minimize the number of times this will happen. If you think in a typical production Rails application, you probably got some exception handling. You know some exceptions will happen from time to time, and so you've got to have your begin and rescues in that. And then hopefully you've also got some sort of exception notification. And that means that when an exception that you haven't planned for happens, you get an email and you know that you can go in, you should go in and fix it. So, there are an analogous set of tools when you're setting up your own servers. And these are called monitoring tools, and they're really, really simple. They're essentially just a list of checks that say, here's how something ought to behave. If it's not behaving, here's a command that you can run to try and fix it. If it's still not working, here's the person to notify and how to notify them there's a problem. And that might sound a little bit daunting. So every time you set up an application you're gonna have to think about all these checks. In practice, this is where configuration management comes in. So, if you remember in that first demonstration, when I uncommented that Redis role, as part of that Redis role, when I originally wrote it, probably a year or a couple of years ago, I included the monitoring configuration for it, which basically says, is Redis working? If no, restart it. If it's still not working, email me. And now that will get automatically setup every time I include that Redis role. So there really isn't that much duplication. Configuration management just does all of this for us. So to get a bit more practical, if you decide to, to go ahead and try this. This is the stack that I end up using, probably 99% of the time. For a web server, EngineX, really popular in the Rails community. There's lots of really great Rails-specific documentation out there. For an app server, Unicorn. This probably isn't what you're using in development at the moment. That's more likely to be Thin or Webrick. Unicorn's a little bit more complicated. But, for that little bit of extra complexity, you get some really nice features. In particular, it's very easy to set up what's called zero-downtime deployment, which you may already be familiar with. Essentially what this means is, the simplest way to deploy an application is to deploy your new code, stop the existing application, and then start it again with the new code. The problem is, if you've got a big Rails application, it can take two or three minutes to start up. And that means that, for two or three minutes, every time you deploy, your app's offline, which is pretty bad for your customers if you're doing this five, six times a day. With Unicorn, you can set it up so that when you deploy new code, it will start up your app in the background, and only once it's ready will it switch it over and stop the previous version, so your customers don't notice an interruption. For a database, I typ, by default go with PostGres. Again, you've probably all heard of it. Very popular in the Rails community. I recommend it to people, because if you're on the Heroku free plan, it's probably what you're using already, because it's their default database. The only controversial item on this list, because all lists should have at least one controversial item, is probably Monit. And it's a bit controversial because there are some amazing monitoring tools out there which are written using Ruby syntax for defining rules. I keep coming back to Monit because it's tiny. Its syntax isn't quite as nice to work with as some of the others, some of the others, but it uses absolutely no memory, and once you set it up, it just stays out of the way and works, which is pretty much what I look for in a monitoring tool. For setting up your server, so your server provisioning tool, I recommend getting started with Chef Solo. Chef Solo is the tool you saw me using in the first demonstration. And it's designed for deploying individual servers from your development machine. What's really nice about Chef Solo is it's built on top of a much bigger piece of software called Chef Server. And Chef Server is designed for when you need to deploy lots of servers in complicated configurations. So, if you need, eventually, to move on from your simple single-box configuration to much more complicated ones, almost everything you've learnt using Chef Solo will be applicable to Chef Server. I mentioned, previously, there were lots of deployment tools, automation tools out there for Rails. Probably the best-known one is Capistrano. At the moment, there are two stable versions of Capistrano out in the wild. There is Capistrano 2 and Capistrano 3. Most of the documentation and tutorials that you find will probably be for Capistrano 2. Despite that, I recommend starting off with Capistrano 3, if you are starting from a blank slate. The reason for this is that version 3 was a complete ground-up rewrite of version 2. In particular, it's just a rake application. So Capistrano 3 is just a, a layer on top of rake that provides deployment-specific functionality. And that means that any knowledge you've already got of how to write rake tasks and how to interact with rake tasks and how to debug them is directly applicable to Capistrano 3. And that just makes the learning curve that little bit shallower. So next steps, if you're gonna give it a go. I suggest you go and get a VPS. I suggest starting off with a one gig one. You can run a Rails app on a 512 meg VPS. You can also spend a huge amount of time troubleshooting out of memory hours, which I think is the least enjoyable thing possible. You can get a one gig VPS for about ten dollars a month at DigitalOcean, I think. They're also a sponsor, and they're really generous with free credit. So if you corner them in a booth, I imagine you can get at least a few months of experimentation for free. So, the url at the top there, talkingquickly dot co dot uk slash deploying_rails. That's a page specific to this presentation, and it contains links to two key tutorials. The first one goes through step-by-step how to set up a Rails server in the way I did in the first video, and the second one is how to set up Capistrano with a new or existing Rails application, as per the second video. They also include the complete sample code that I'm actually using in production, pretty much every day, for deploying new Rails apps. So, hopefully, the fairly large amount of time I put in originally trying to work out how to get a working configuration management set up, you can take that as a starting point and get it started very quickly. It should take maybe an hour and a half to get your first server set up and an app deployed to it. I mentioned at start, I've also written a book about this. Reliably Deploying Rails Applications. This was basically the reference that I wish I'd had when I started doing this. It uses exactly the same sample code as those tutorials. So if you start off using those and find you want to do more complicated things, hopefully that will be a useful reference. And there's a discount code, et cetera, for RailsConf attendees on that link. Finally, I'll be in the AirPad Pit at 4:30 today. So if anyone wants to give this a go for real and wants a hand setting stuff up, I'd be very happy to help out. Yeah. Thank you so much for coming to the talk. I've really enjoyed doing this. Let's have some questions.