rails development server for windows - ruby-on-rails

I need a recommendation for a rails web server to use for development on windows. I was happy with the default rails server until I had to handle two concurrent requests which it does not support (a page calls an internal rest service). I want to keep the "rails s" experience, so which is the simplest server that support my needs?

To my knowledge, there is no Windows-compatible Rails web server that is multi-threaded or concurrent out of the box.
You will need to spawn multiple back-end servers (we use mongrel, you could use thin instead) and then use/configure a proxy server (we use nginx) in front of them to handle multiple requests concurrently on Windows.
This blog post describes setting up Thin and nginx on Windows, once running you can edit the nginx.conf to proxy to multiple thin instances/ports.

Related

How can a Rails app run with Puma alone by default - without a web server

A web application that generates dynamic content requires two components:
Web Servers - primarily communicate with clients, by handling HTTP requests and responses while serving content.
Application Servers - on the other hand, generally sit behind a web server. If the web server can not generate the requested content via static files, it then reaches the application server to generate the dynamic content.
Software Examples
Examples of web servers include Nginx and Apache
Examples of app servers include Puma and Unicorn
Web servers and application servers work together as components in typical web applications.
Running Rails in Production
When running a Rails app in production using passenger, some options include:
Running Passenger as a stand alone solution
Running Passenger as an app server and Apache/Nginx as the web server
Running Rails in Development
When running a Rails app in development, it is configured to use Puma by default - see Ruby Docs. Puma is an application server. How is it that by default, in Rails, Puma can run the entire web application on its own? There's no mention of a web server like Nginx or Apache in the application stack.
I don't understand how this is possible. Can someone please explain this? Puma has always been an application server, not a web server...
Thanks in advance.
The distinction between a "web server" and an "application server" is rather muddy and has a lot of implicit (and mostly historical) baggage.
Generally, a web server is understood as a software which communicates via HTTP (or HTTPS) to clients and send static files as a response to requests.
An application server on the other hand often does not communicate directly with clients (but instead with intermediate server systems in front of it, such as loadbalancers, proxy servers or well, web servers) and its main function is to respond to requests with dynamically generated content. Application servers sometimes communicate with those intermediate servers using protocols other than HTTP, such as FCGI or AJP.
Often, we will see classic webservers (such as nginx, Apache, lighttpd) used together with an application server such as Puma, Unicorn, Thin, or Passenger. The reason for that is that those webservers are more efficient in serving static files than the application servers which are more geared towards helping the application generate dynamic responses. Also, web servers might be better suited than application servers for buffering requests and responses from clients without using a lot of resources.
With that being said, in the last couple of decades, it became increasingly common to just use HTTP everywhere rather than to use e.g. FCGI internally. Thus, application servers are generally able to speak to HTTP clients on their own without strictly requiring an additional web server. Often, these application servers can also serve static files directly and thus take on most features of a webserver too.
However, as written above, most webservers are magnitudes faster and more scalable when serving static files. Also, some application servers such as Unicorn are not intended to be exposed to clients directly since Unicorn does not buffer requests and responses efficiently. Instead, they rely on a frontend server such as nginx for that.
Thus, as a conclusion: most Ruby application servers can be used without a webserver directly. With e.g. Puma this will work quite okay. To more efficiently serve static assets, or to loadbalance or protect your application, you can also introduce a webserver / proxy in front of your application server such as nginx or Apache.

Why do I need Nginx with Puma?

I'm deploying a Rails app to production. It seems that Puma is fast and handles many of the things I want in a web server.
I'm wondering if I even need to bother with Nginx, and what I'd be missing out on if just used Puma?
Nginx is a web server and puma is an application server.
Both have their advantages, and you need both.
Some examples:
Static redirects- you could setup your nginx to redirect all http traffic to the same url with https. This way such trivial requests will never hit your app server.
Multipart upload- Nginx is better suited to handle multipart uploads. Nginx will combine all the requests and send it as a single file to puma.
Serving static assets- It is recommended to serve static assets (those in /public/ endpoint in rails) via a webserver without loading your app server.
There are some basic DDoS protections built-in in nginx.
There's a significant difference between a web server and an application server.
Nginx (Web Server) and Puma (App Server) will handle requests in your application simultaneously.
Whenever there's a request coming from a client, it will be received by the nginx and then it will be forwarded to the application server which is Puma over here.
Having nginx as a web server will help you in handling multiple requests much more efficiently. Being a multi threaded server it will distribute requests into multiple threads making your application more faster.
As mentioned by vendant you can serve static pages using a web server as it will be a better approach.
If you're going to include a certification to your web application then you can provide redirects from http to https over here which will hit the app server only after redirecting to https.
If you're going to use Puma then you've to make sure that server is using resources efficiently but if you'll use nginx then it's going to take care of it by itself.
you can get more info here.

Is one rails server per application?

I have two questions about rails server:
Do I have to start the server from within the application folder?
Is the server I started only for that application?
If they are true, this does not quite make sense to me, since why do I need to start multiple servers?
Or is there some kind of master configuration, so that one server can route to different applications? Is Capistrano for this purpose?
I'm going to assume you're talking about the rails server command, for running a local rails server to test your application, and that you're not talking about setting up a rails application on a remote server. Please mention if that is not the case.
Yes, you must execute rails server from within the root folder of your rails application.
Yes, the server you started is only for that application. It's a self-contained thing.
You should not need to start multiple servers. Even if you have multiple applications, you probably don't need to have more than one running at a time. So, you can shut down the rails server in one application (Ctrl-C) and then cd to your new application, and start a new rails server there with rails server.
If you do need to run two local rails applications at once, you can do so by running them on different ports. So, the first one, you can just execute rails server and it will make your site available at localhost:3000 (because port 3000 is the default port). The next one, you can specify a port other than 3000 - eg. rails server -p 3001 to get a rails app at localhost:3001.
Capistrano is for deploying your applications to a remote server, not for running them locally on your own computer. So, it is not relevant here. What you may be interested in is http://pow.cx/
Again, I've assumed you're talking about running your rails app locally on your own computer. If you're referring to deploying it to the internet on a server, then you can ignore this answer.

Deploying Rails and Nodejs

I wrote a real-time web app that consists of the following:
Rails to serve the web pages (listens on port 80)
Nodejs to handle real-time logic (listens to port 8888)
So on a particular page served by my rails app, the JS will use socket.io to establish a connection to my nodejs instance to allow real time http push.
Currently Nodejs communicates with Rails simply by updating the rails database. (I know this is ghetto but it works).
What are my options for deployment?
I have deployed simple web apps on heroku before and I really like the simplicity.
I have also deployed a web app with similar functionality (except it's made up of django + nodejs). I used HAProxy to do reverse proxying to handle direction of traffic to the correct process on my machine. However, I deployed this on a VPS server instead.
Note: the ugliness will probably revolve around:
I am relying on a common db
These processes are listening on different ports
We had this exact issue. We deployed them to separate Heroku applications, but kept them within the same code base. http://techtime.getharvest.com/blog/deploying-multiple-heroku-apps-from-a-single-repo outlines how to do it.
Manually set the buildpack
Set a config variable that you can reuse in step #3.
Create a custom web script that your Procfile uses
A custom script in bin/web
#!/bin/bash
if [ "$RAILS_DEPLOYMENT" == "true" ]; then
bundle exec rails server -p $PORT
else
node node/index.js
fi
And the Procfile:
web: bin/web
I would consider setting these two applications up as separate Heroku applications on different subdomains and just having them both on port 80. The communication between them goes through a shared database so they don't need to reside on the same machine or even datacenter. Socket.io supports cross domain requests on all browsers, so that shouldn't cause any problems.

Serving web application without Lighttpd/Apache

As Rails applications default run on port 3000, would it be possible to start the application on port 80? Is it really required to have a fastcgi/mod_proxy enabled web server in front? My users won't be more than three at a time. If so, how would I be able to do so?
Thanks!
WARNING: This is not a general purpose description of how to set up a Ruby on Rails production environment. If you want to host a public Rails website, I highly recommend using Apache with Passenger, which is very easy to install and maintain.
From your description, it sounds like you are working with some kind of internal application to be used within your office or similar. For this particular purpose, hosting the application via Webrick (the built-in web server in Rails) might be a sufficient solution. To do this, start the server with a -p command line argument: ruby script/server -p 80
This obviously requires port 80 to be available (not bound by some other web server). Also, on most operating systems, you will need root privileges to bind to port 80. The security implications of running a web site as root are serious, so you really only want to do this if you know what you are doing, and are absolutely sure that the server is completely shielded from the Internet.
If there isn't some specific reason you're trying to run with mongrel, I would recommend using Phusion Passenger as it is significantly easier to configure and support than mod_proxy+mongrel.
mongrel - http://github.com/fauna/mongrel
thin - http://code.macournoyer.com/thin/

Resources