What does it mean to run a local web server? - ruby-on-rails

I can program and develop in Ruby on Rails/JS/HTML/CSS to make a full stack app. However, there are holes in my understanding of the HTTP request/response cycle. Are the following points correct?
If I make a Rails app, and on the command line type rails server I get a local server, which I can make requests to. If I open a browser, type localhost:3000, and press enter, I am making an HTTP request to the local server.
Rails uses by default a web server called WEBrick, though there are others like Thin, Puma, and Unicorn. These are all pieces of software, and what makes them web servers is the fact that the software implements functionality to process HTTP requests.
When I run a local web server, it means that my computer is running one of these pieces of software that listen for HTTP requests.
Is the above what it means "to run a local web server"?
I have seen other examples of ways to "run a local web server". One of the is to run npm install -g http-server in a project directory, and then navigate to localhost:8080. Is this also just software that starts running and accepts HTTP requests on port 8080?
On a Ruby command line, install rack gem: gem install rack. Then in a new Ruby file we require 'rack', start a web server:
Rack::Server.start({ app: MySimpleApp, port: 3000 })
We can then define a web application MySimpleApp that is rack-compliant (object that responds to call method):
class MySimpleApp
def self.call
(...)
end
end
So now when we navigate in our browser to localhost:3000, MySimpleApp is executed. Is rack simply running it's default WEBrick server? Is what the above commands do simply run a local web server and define what to do when an HTTP request comes in (execute MySimpleApp)?

You're pretty much right on your understanding there. HTTP is just a text-based protocol that, like many, operates over TCP/IP.
The built-in WEBrick server isn't the best example of an HTTP server written in Ruby, but it's included for legacy reasons because it's often "good enough" to get you started. Pow is considerably better and despite being produced by the same company that produced Rails it's largely written in Node.
The beauty of HTTP, like a lot of internet based protocols, is it doesn't matter what language you use so long as you comply with the standard.
Rack is a layer that operates behind HTTP and provides a thin layer of abstraction on the request/response cycle.

A server is something that opens up a port (80, 443, 8080) for some sort of data transfer. Port 80 is the HTTP port and port 443 is the HTTPS port. 8080 is a commonly used port for development (as is 3000). https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
A local server by definition is a server running on your machine.
Overall, you are definitely on the right track.

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.

What is localhost:8000 as used in Codecademy (for AngularJS and Ruby on Rails tutorials)?

I want to know what is this: localhost:8000, found in Codecademy tutorials for AngularJS and Ruby on Rails. I even installed Apache 2, but to work with it I need to dial: http://localhost/. While working on some html files, I often come across Firefox's Inspect Element where a section is to mention localhost and its number like this: localhost:8000. I want to know what's this and can I use it to access my host from my android device or some other PC as we do access Codecademy's localhost to learn AngularJS and Ruby on Rails. Pls help. Thanks in advance. :-)
Localhost is the loopback-address of your pc. The IP-address behind it is 127.0.0.1. With localhost, it is possible to simulate a web-server environment and it is mostly used to simulate running web-applications as if they are running on a webserver. :8000 stands for the port-number on which the browser connects to the server. This is because the application runs (in this case) on port 8000 of the server. So it is not enough to just install Apache 2 and surf to http://localhost/ you have to configure Apache so that it runs your web-application on the desired port. The port-number itself has no special meaning. The different ports are just a part of the url so the browser knows on which port it has to connect. Some protocols use default ports. (e.g. HTTP will always connect to port 80, unless your specify another port in your webbrowser)
I'm sure a lot of people can explain it much better, but here is a begin.
More info about running ruby on rails on an Apache webserver:
How can i run a ruby on rails project on apache server?
How to setup Ruby on Rails Hosting using Apache, from Development to Production
EDIT: Technically, the whole 127.0.0.0/8 address block is reserved for loopback purposes. The default one, configurged in hosts.txt is 127.0.0.1 and the most famous.

Separate port for some URLs in Rails app

My Rails app listens on single port for API calls and browser requests. To increase security I would like to open another port for API and make web page URLs unabailable for this port.
How to do this in Rails? (Possibly without losing current app integrity).
I use WEBrick or Puma during development and Apache+Passenger in production.
P.S.
Currently I'm thinking about making HTTP proxy which will forward API calls.
Unicorn will bind to all interfaces on TCP port 8080 by default. You may use the -l switch to bind to a different address:port. Each worker process can also bind to a private port via the after_fork hook. But I think it is not useful if you have nginx on top layer.

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.

rails development server for windows

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.

Resources