You may have heard that Kubernetes is for modern cloud-native, microservices-based applications. Does that mean you can't run it with a monolith Rails application?
Not quite. Technically, nothing will stop you from just deploying your Rails application on Kubernetes. It'll work just fine. But there are a few things to consider to decide if you actually should.
Let's take a look.
Rails on Kubernetes—Why?
Let's start with the most important question: why would you want to run your Rails application at all?
As we already mentioned, Rails applications are monolithic, which means most of the application logic is combined into one piece. And Kubernetes was designed to run distributed, a microservices-based application where one application consists of multiple smaller pieces. So, it sounds like it's not a good fit for Rails, right?
Well, at first, indeed, it does. But let's dive a bit deeper into it.
What's your alternative? Running a Rails application on a normal server, right?
And do you have only one server for your Rails application? If it's a very small application or you just started with Rails, then possibly.
But in most production situations, you'll actually have a few servers working together for one Rails application. This includes one server for the Rails itself, another server handling access to your application—so, for example, NGINX and Puma—a third server for Redis, a fourth server for a database, and a fifth server for background jobs like Delayed Job or Sidekiq.
On top of that, you'll probably have some load balancer in front of all that and maybe yet another separate server or a dedicated solution for storage.
And, suddenly, you realize that your monolithic Rails application actually requires a dozen servers and not just one.
The Problem
The problem with that approach is that it's not very flexible, and you need to make a lot of compromises. For example, some of your servers may be heavily underutilized most of the time, but you can't scale them down because, from time to time, there is a spike in traffic. And the bigger the application and the more servers you have, the more resources that are probably wasted—or, to put it nicer, not used efficiently.
Another thing is that it'll take a lot of time and effort to get all these servers maintained—periodic system upgrades, making sure they all have enough free disk space left, etc.
Adding a new server when needed will probably take a while, too. You'll need to deploy it first, then configure the operating system, then install what's needed for Rails, and finally make sure it connects properly with the rest.
Enter the Kubernetes World
The problems stated in the previous section bring us to Kubernetes. You could simply put all your Rails application pieces to Kubernetes and not worry about individual servers anymore. Kubernetes abstracts infrastructure from you, so you won't need to worry about underlying operating systems, security patching, etc.
Sure, your Rails application will still be a monolith, so you won't get all the benefits of Kubernetes, but you'll get some. All the extras that your Rails application may need will still be deployed on Kubernetes as separate pieces, so you'll still benefit from easier scaling and node management.
And, last but not least, once your Rails application is on Kubernetes, you'll have an easier path to start decoupling your monolith in microservices if you wish to do so.
How to Use Rails on Kubernetes
Now that we know some theory, let's see in practice how to run Rails application on Kubernetes.
In fact, there's nothing special about running Rails on Kubernetes in comparison with other frameworks. You'll need to package your Rails application into a container and create a YAML manifest file in order to deploy it on Kubernetes.
Let's start with the container. There's no single specific way of packaging Ruby on Rails applications into a container—a lot will depend on how your application is working and how many best practices you want to implement, but here's a good starting point.
Docker Container
Save the above as Dockerfile (with no extension) in your Rails project root directory, and then build your image:
OK, that's pretty much it. That's how you package a Rails application into a Docker container.
Now what?
We could start writing out Kubernetes manifest, but it's best to first check if our application is working in the container properly. To do that, run that freshly built image by executing docker run -p 3000:3000 rails_on_k8s:0.1, and then open your web browser and head to localhost:3000.
If you see your application, everything is good, and we can proceed.
Kubernetes Manifest
OK, we're ready to write a Kubernetes deployment manifest for our Rails application.
It'll be a fairly simple deployment at first. The only thing you need is to upload your Docker image to some container registry. If you don't have your own private repository, you can use a free account on dockerhub.com. You'll need to register there and follow the instructions on tagging your image and pushing it to the registry.
Once you have your image ready in a container registry, you can create a Kubernetes manifest:
Once created, it's time to deploy it. We'll use the kubectl apply command and pass the YAML file with the -f parameter followed by the file name:
OK, it looks like it worked! Let's check:
It seems like, indeed, we successfully deployed our Rails application on Kubernetes.
But here's the first tip for you. The fact that your Rails pod is running doesn't actually mean that the application inside is too. Without proper checks added to our deployment definition, it's possible that our Rails server actually failed to start properly and Kubernetes doesn't know about it.
To validate if the application in the pod is indeed running, we can first check the logs:
That looks promising. It seems like our Rails server started properly, so, most likely, everything is good. But the ultimate test would be just to try to access the application. To do that, we first need to expose it somehow. In the Kubernetes world, we do that using Kubernetes services.
Kubernetes Services
In order to create a service for our Rails deployment, create another YAML file with content similar to this, but keep in mind that you may need to adjust the type of the service based on what kind of Kubernetes cluster you're using:
Apply the above using kubectl apply:
Now, after a few seconds, we should see the IP address of the load balancer that exposes our application:
And if you open that IP address in your web browser, you should see your application, which in our case is showing a simple "Hello world" message:
All works well, then. We have a Rails application running on a Kubernetes cluster.
But this was just a simple example when we only deployed our Rails application. If that's all you'd do, it probably won't give you many benefits to move to Kubernetes.
Earlier in this post, we mentioned that it makes sense to move your Rails application when you have lots of other components supporting your application.
And if you do, the process of moving them to Kubernetes would be very similar. You either create a Docker image from scratch for all the components you need or search for ready-to-use images. Companies behind well-known tools like Redis or NGINX are publishing images themselves, so it's a little bit easier to onboard them on Kubernetes.
But What About the Database?
This is a fair question. The database is really important for Rails. Databases can run on Kubernetes too. But depending on your specific needs and due to the nature of databases, it may make more sense to use an SaaS database or keep it on traditional servers.
You can easily keep your Rails application on a Kubernetes cluster and have it connected to the external database. Of course, for performance reasons, however, you should keep it as close as possible to your Kubernetes, which means ideally in the same cloud provider, the same region, and even the same network.
Rails and Kubernetes Summary
We've only touched the tip of the iceberg here when it comes to Kubernetes, but you learned how to package your Rails application into a container and deploy it on Kubernetes. From there, the next steps will depend on your application and company specifics.
Kubernetes itself is a complex system and gives you multiple choices when it comes to deploying applications, networking, and storage. But you now know how to use it for your Rails application and when it wouldn't really make too much sense.
If you're interested in learning more about Kubernetes, check out our blog here for more posts about it.
About Release
Release is the simplest way to spin up even the most complicated environments. We specialize in taking your complicated application and data and making reproducible environments on-demand.
Speed up time to production with Release
Get isolated, full-stack environments to test, stage, debug, and experiment with their code freely.