Rails applications might be easy to develop but they do rely on a number of things. Let’s explore them:

Web Server

You probably already know what they are. Web Servers like nginx and apache take in a HTTP request, map them to a resource on the server, hold the connection open while the resource can be fetched and return the result to client. They also handle HTTPS (SSL), pool connections, balance load and enqueue requests.

Both Apache and nginx are very powerful while nginx being the faster one in terms of raw performance and other capabilities such as load balancing and holding a lot of connections open at a time.

Application Server

If you have developed a Rails app, you probably have typed rails server (or rails s) in a console and have navigated to http://localhost:3000 to check if your application works. With time you must have become used to it. But it is worth learning what is happening in there.

What is happening is that running rails server tells Rails to start the web server and serve pages. This starts puma. You might have noticed something like this:

=> Booting Puma
=> Rails 5.2.1 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.3-p105), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

Depending on your Rails version, it might be a little different but it is something like this for most parts. What is happening here is that Rails is starting puma server. puma, unlike nginx or Apache is not a web-server. It is a application server. What application servers do is keep your application running - in this case, puma keeps your Rails application running. If it were not for puma, your Rails application would boot up, serve the request and die. This is not a great thing because booting up a Rails application takes a lot of time and so, it’s better to keep the application in memory and send it requests as and when they arrive.

If you come from PHP world (like a lot of other web developers), the concept of application servers would look a bit strange. The closest thing you can think of an application server in PHP world is PHP-FPM which takes in a requests and forwards it to a process that it can control and passes back the response to the web server (nginx/apache). Application servers are fairly common in non-PHP side of things. NodeJS can act as an application server, popular Java and Python frameworks also depend on application servers.

In case of Rails setup, most of the time, the web server forwards the requests to the application server which then gets it processed by the Rails framework and returns the result to the web server, which then returns the result to the client (e.g. browser).

How are application servers different from web servers?

Natually, the question arises - if you can launch puma and serve requests already, why not just run puma on port 80 and let it handle the HTTP traffic? Afterall, that’s what we are doing anyway - serving requests via puma, right? No.

Application servers’ main focus is on keeping your application running. Depending on which application server we are talking about, they do have some settings to manage multiple requests, manage memory etc. but they lack support for a number of functionalities that web servers have.

Here are some of the major differences:

  1. Application Servers are normally written in the same language as the framework they can server. For example, in most cases, Rails application server would be written in Ruby. This is not always the case, but it is normally the case.
  2. Application Servers are not meant to handle multiple sites and paths in a single instance. On the other hand, both nginx and Apache (and others too) can handle multiple sites on a single machines using VirtualHost configurations or server blocks in their configuration.
  3. Application Servers normally do not forward request to another server - they forward request to the application. Web Servers can be configured to forward requests to whatever place you want to. nginx, for example, can be used as a standalone load balancer!
  4. Redirection/Rewrite of incoming requests according to the path requested is something which is normally done at the web server level, not the application server level.
  5. Application Servers normally do not handle SSL well. So if you have to manage a HTTPS site, more importantly one which needs multiple servers/containers to run - you are going to find it much harder to do that on Application Server level alone.
  6. Quite importantly, most Application Servers are slower than web servers. Most popular web servers are written in C or C++ which by the virtue of design are very fast.

Application Servers are called Application Servers for a reason - you should not be confused about them, or try to replace them with web servers.

Database

This one’s a no-brainer. If your application saves data somewhere, it would need a database. For most basic purposes, a Relational Database Management System is required. That might not be the case for all applications - some might not depend on a RDBMS at all and can work with NoSQL solutions like MongoDB or CouchDB and then there can be some which do not save any data (for example, a chat application server might not want to save the chats it transmits).

However, in most cases, you do need a database. PostgreSQL is normally preferred in Rails application but other databases like MySQL, MS SQL, Oracle are well-supported.

Operating System

We are talking about Operating Systems near the end of this page because Linux is the default choice in most cases. If you are using Windows for running a Rails app in production, then this guide will not work for you. If you use Windows only for developing a Rails app, the guide might still work but you should know what you need to do on Windows as a corresponding step because I do not or intend to care about Windows.

Let’s proceed to the tools selection.