00:00:16.440
Okay, okay! 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 time teaching people at Make It With Code, which is an online mentor-driven class for those who are new to Ruby but want to start creating things quickly.
00:00:20.860
I spend the rest of my time working with some folks at Hello Swim IO, where we create cool technology for swimmers. We develop things like the timetabling system for the Olympic Pool in London, Speedos' tracking app, and the first automatic lap tracker for the Pebble smartwatch.
00:00:27.520
So before we get started, could you raise your hands if you've deployed a Rails app to Heroku? Awesome! Now, keep your hands up if you've deployed a Rails app to a server that you set up yourself. Good, that’s less people. If someone came to me and said, 'I want to deploy my first Rails app, how should I do it?' I wouldn't think twice—I would just say, 'Use Heroku.' I advocate Heroku because it simplifies the app deployment process incredibly. You just commit your code, create a Heroku app, push it, and magically, a couple of minutes later, your application is live on the internet for the world to see.
00:00:54.390
Because Heroku makes this process so simple, it's easy to push the server-related tasks away into a category of things we don't examine since it's perceived as complicated. However, I'd like to demonstrate in this talk that in the same way Rails makes building web applications really straightforward, there are many great tools that facilitate setting up servers and deploying to them smoothly. Once you understand how these tools work, you can accomplish some truly fantastic things. Before diving deeper, let's define two important terms that you probably may already know: PaaS (Platform as a Service), which refers to something like Heroku that abstracts away your infrastructure so you don't have to worry about it; and a VPS (Virtual Private Server), which, for the purposes of this talk, means a form of Linux server operating in the cloud—offered by providers like Linode, Rackspace, or Digital Ocean.
00:01:39.910
Now, to get started, let’s take a brief look at what's happening behind the scenes when you deploy a typical Rails application. How do we transition from a Rails app developed in our local machine to hosting it on a VPS that serves our application to the world? Here’s a diagram I created for this presentation depicting a VPS. One crucial takeaway for many people is that for a simple production configuration, you only need one VPS. Just like we can run a whole Rails application on our development machine, we can run everything efficiently on a single VPS for basic production applications.
00:02:50.530
This VPS will generally consist of three main components for almost all Rails applications: a web server, an application server, and a database server. When someone types the web address of your application, a request is sent to your VPS, which first reaches the web server. If the request is for a static file—anything within the Rails asset pipeline or anything found in the public folder—the web server handles it directly and returns that file to the user’s browser. If the request is for a dynamic page, like what a Rails app would generate, it is routed back to the application server.
00:04:33.210
When we run 'rails s' in development mode, we are starting an instance of an application server. This application server acts like the Rails server running on a VPS. The web server parses the incoming request, forwards it to the application server, which generates the response and sends it back to the web server, which then returns it to the user. In development, we often use servers like Puma or WEBrick. For production, we may opt for Puma or Unicorn, which offer more advanced features.
00:05:48.100
Nearly every Rails application will require a database server, typically either PostgreSQL or MySQL. Again, we don't need a separate database server; it can run on the single VPS, too. To summarize: a request arrives and reaches our web server, which may be Nginx or Apache. If it's for a static file, the web server handles it. If it's related to our Rails application, the request gets passed to the application server, which performs necessary database actions, constructs a response, and sends it back to the web server, ultimately returning it to the user.
00:06:02.250
You may look at this and think it appears more complicated than using Heroku. Why would you go through that trouble instead of just utilizing Heroku? Honestly, I began pursuing this path primarily due to cost. I manage several side projects, and you likely know that most PaaS solutions charge based on the number of processes. With multiple personal projects and background jobs needing separate Heroku dynos, that bill can quickly add up month after month.
00:07:31.100
To save money, I transitioned to deploying to my servers, and it was beneficial. However, it's important to keep in mind that, just like any new skill, you have to invest time to learn it. While considering the time invested in these projects versus market rates, I found there were no savings at all. For personal projects, I didn’t pay myself market wages, so it was more of an investment rather than a cost.
00:08:03.100
Moreover, the biggest advantage of learning how to manage my infrastructure had little to do with money. It shifted from being an obligatory evil necessary for running my Rails apps to being just another tool for building interesting projects. For example, at Make It With Code, we provide students with a cloud IDE that has Ruby pre-installed, allowing them to jump straight into coding. The techniques we utilize to set that up automatically mirror what I will cover in today’s presentation about establishing Rails apps. The infrastructure has evolved into something that adds value to our overall product.
00:09:17.090
Now, if you decide to take this on, I sincerely urge you not to emulate my original approach. Mine was fraught with mishaps. I started by getting a VPS that worked moderately well. After some Googling, I found various tutorials that told me to input a command, then another, followed by editing a configuration file. I stumbled upon a plethora of helpful Stack Overflow threads for troubleshooting. Eventually, I had a functioning server that was stable for a while, but then it broke.
00:10:39.140
Unfortunately, this occurred while I was on holiday in rural France, where Wi-Fi access was limited. One morning, while trying to check my email, I received a notification from my host stating, 'Dear valued customer, your server is dead; you need to create a new one.' So, I set up a workspace in that wardrobe and spent the entire day trying to replicate what I had done before, following the same tutorials and making the same initial mistakes. While I successfully restored connection, the process was not any easier on my second attempt, which is quite frustrating. It made me realize that there had to be a better way.
00:11:54.610
In truth, I initially thought, 'I can’t believe there isn't a better method.' I thought about inventing one, hoping it would lead to wealth and fame. However, I took a step back and acknowledged that such tools already existed. What I was in need of was a configuration management tool. These tools allow you to define and automate the commands necessary to set up a server to perform particular functions. One of the best features of configuration management tools is that after the initial setup, redeploying or creating identical environments becomes trivial.
00:13:01.530
To give you an idea of the simplicity here, I’ve prepared a brief demonstration of the exact process I use weekly to set up new servers. At the end of this presentation, I’ll link you to tutorials illustrating how to accomplish this yourself along with the sample code, so you won’t need to stress about memorizing every step; I just want to give you an overall perspective of how straightforward it can be. On the left of the screen, there’s a list of previous servers I've deployed. I’m using my chosen configuration management tool, Chef, which utilizes JSON files for specifying what goes on a specific server type.
00:14:30.280
If I want to add a new web server for Make It With Code, which currently runs a selection of Rails apps, I simply create a new JSON file. The server will be much like one of the existing setups, again running Rails applications. I copy all the JSON from the previous server into the new one, and then the significant note here is about the run list at the bottom. You can see a list of roles that define individual components that can be combined to specify what should be installed on the server. In previous configurations, I dropped in definitions for Nginx and Postgres servers, so when I want one, I can quickly integrate into the stack.
00:15:43.940
After adding the configurations needed, I can run a command called 'knife solo bootstrap' followed by the VPS address. I can then let it run while I grab a coffee. The output shows the commands being executed, the changes made, and if something goes amiss, it will point out what was being done at the time of the error, so I can swiftly fix it. After this process completes, I will have a Rails server identical to the last one I set up. I can check that it works by loading a web browser and going to the provided URL, confirming that the server is configured and operational.
00:17:23.550
What I want to illustrate with this example is that configuration management embodies the principle of 'Don't Repeat Yourself' in server setups. If you reflect on your first experience, say with Devise, for example, it was probably an arduous process. Yet, when you return to it after some time, you often forget what you did last time but can quickly refer to the code you wrote and take snippets from it. In contrast, manually entering commands lacks an inherent audit trail of what was done initially to make it work. As a result, when you attempt a second setup, you might repeat the errors encountered the first time.
00:18:32.840
Utilizing a configuration management utility, you automatically create an easy access audit trail, so the upfront time investment pays off significantly over time. Hopefully, I've shown that setting up a server doesn’t have to be overly complicated. I will provide the practical sample code at the end that you can utilize for a head start! Platforms like Heroku not only make server setup incredibly straightforward, but they also streamline the deployment process. A simple command like 'git push heroku' makes deploying nearly effortless.
00:19:54.670
I found that when I first used Heroku, it revolutionized my workflow. Coming from Python’s Django and PHP, I had relied on various homegrown deployment systems—ranging from tracking changed files and FTP transfers to custom shell scripts. All of them, unfortunately, had issues and prevented reliable deployment, which made the process quite anxiety-inducing.
00:21:05.640
Heroku changed that for me, allowing me to deploy multiple times a day seamlessly. If I were to deploy servers on my own, it would need to be just as simple. Luckily, there are clever individuals in the Rails community who shared similar thoughts and thus developed great tools, including gems that significantly simplify the server setup process. The most well-known of these tools is likely Capistrano, which I'll discuss more towards the end of the presentation.
00:22:29.270
Next, I'd like to give a brief demonstration of integrating Capistrano into an existing Rails application. Please don’t worry about the specific steps at this stage; I will provide a complete tutorial and accompanying sample code later. To get started, it involves adding the Capistrano gem into your Rails application along with a few supporting helper gems, saving it, committing to git, and running a command to generate some basic configuration files.
00:23:33.440
Among the generated files is a Capfile—a rake file for Capistrano. Here, I indicate the helper gems I want to utilize. The main config file, deploy.rb, specifies the application name, the git repository from which to deploy, and I can remove unnecessary boilerplate for simpler applications while indicating necessary configurations like the Ruby version to use during deployment.
00:25:03.930
Next, I setup configurations for different environments, for instance, defining the production server as 'web3.makeitwithcode.com,' which has been set up in the demonstration. I can then run a command called 'set up config,' which prepares the server for a new application. This generates necessary configuration files and creates a new database, ensuring that all users have access.
00:25:22.470
The critical command 'cap production deploy' serves as our equivalent of 'git push heroku.' The output shows typical deployment tasks such as applying migrations, compiling assets, and restarting the application server.
00:25:39.780
Once completed, I can check the app in a web browser, confirming that the application is functional and connected to the database, allowing data retrieval and updates, thus enabling a continuous iteration process on the application.
00:26:00.969
While setting up your server may be easy, the significant advantage of using PaaS like Heroku is that when something goes south at 2 a.m., it isn’t your problem anymore—engineers are available to resolve issues, and your application comes back online without your intervention.
00:26:40.000
Although we now shoulder the responsibility of our servers, there are tools and techniques to minimize potential issues. In a typical Rails production environment, you should incorporate exception handling to manage anticipated issues effectively. Additionally, you should implement monitoring tools that automatically check server health and functionalities.
00:27:20.000
Thinking back to the early setups, where configuration management also becomes beneficial is in automatically creating the necessary monitoring setups when provisioning components like Redis. By integrating those necessary safeguards and monitoring checks into my configuration management setup, every new server I create will inherently incorporate them without needing extra effort.
00:28:20.000
One practical stack I regularly utilize includes Nginx for web server, which enjoys a solid reputation within the Rails community with extensive documentation available, while I often deploy with Unicorn as the app server for its capabilities, including zero-downtime deployments.
00:29:49.000
For the database, I default to PostgreSQL due to its popularity, particularly within the Rails community, and it is likely what you’re using if you are on Heroku's free plan. The only controversial recommendation in this lineup pertains to the unattended monitoring software—Monit. Some may argue there are better alternatives, but I keep turning back to Monit because of its lightweight nature—it demands very little memory and once configured, it runs quietly.
00:30:50.140
When starting your server provisioning, I recommend using Chef Solo, as it creates your individual servers from your development machine. Using Chef Solo effectively prepares you for when you might want to scale and deploy a more extensive range of servers later, applying your earlier learned skills and configurations.
00:32:30.000
Returning to deployment tools, Capistrano is by far the most recognized in the Rails ecosystem. Currently, there are two stable versions available: Capistrano 2 and Capistrano 3. Despite much documentation being available for the older version, I suggest starting with Capistrano 3 if you're beginning fresh, as it has undergone a significant overhaul that simplifies deployment functions.
00:33:30.000
In conclusion, if you plan to implement everything discussed today, I recommend obtaining a VPS—ideally a one-gigabyte instance which can handle a Rails app effectively, sparing you from running into out-of-memory errors with smaller instances. DigitalOcean offers one-gigabyte machines for around $10 monthly, and they often provide free credits for new users.
00:34:53.000
The specific URL related to this presentation is 'talkquickly.uk/deployingrails.' This page includes useful tutorial links, the first being a step-by-step guide to setting up a Rails server corresponding with the demo. The second tutorial walks through configuring Capistrano, also featuring complete sample code used for deploying Rails applications.
00:35:30.000
With this, I hope the extensive time I invested studying configuration management to set up these projects serves as a solid foundation for your ventures into deploying Rails. You should expect to spend roughly an hour and a half to setup your server and deploy your first app.
00:35:53.000
Additionally, I've penned a book titled 'Reliably Deploying Rails Applications,' which serves as a handy reference encompassing the sample code used in the mentioned tutorials, assisting you as you navigate your way to more complex configurations.
00:36:09.000
Finally, I will be available in the Air Pair pit at 4:30 today to provide any hands-on assistance if anyone wishes to try this out!
00:36:38.000
Thank you so much for attending this talk! I genuinely enjoyed presenting it. Let's open the floor for some questions.