Running Sinatra on port 80 - ruby

I installed Sinatra and it works but it uses port 4567 by default. I want it to run on port 80.
In an effort to get it to work on port 80, I tried this:
require 'rubygems'
require 'rack/handler/webrick'
require 'sinatra'
Sinatra::Application.default_options.merge!(
:run => false,
:env => :production,
:port => 80
)
get '/' do
"Hello World"
end
But I get this error:
$ ruby -rubygems index.rb
index.rb:5:in `<main>': undefined method `default_options' for Sinatra::Application:Class (NoMethodError)
Any idea what's going on?

Can't you just use (http://www.sinatrarb.com/configuration.html):
set :port, 80
Note that in order to bind a socket to port 80, you'll need to have superuser privileges.
And, by the way,
Using Sinatra.default_options to set base configuration items is obsolete
From: http://www.sinatrarb.com/one-oh-faq

An alternate way to accepted answer
rvmsudo rackup -p 80
In case one is using RVM to manage Ruby versions, you may not be able to use sudo that easily (or else would need to setup ruby in path).

Any port below 1024 is for privileged processes only. You'd have to run as root to run the sinatra app directly on 80. You could reverse proxy - http://sinatra-book.gittr.com/#deployment.

Yes, running anything other than Apache, Nginx, Varnish or HAProxy or port 80 is in my opiniona dangerous game. Those tools are very good at what they do. A reverse proxy setup is the way to go.

Related

How to make Thin run on a different port?

I've a very basic test app. When I execute this command the server ignores the port I specify and runs Thin on port 4567. Why is the port I specify ignored?
$ruby xxx.rb start -p 8000
== Sinatra/1.3.3 has taken the stage on 4567 for production with backup from Thin
>> Thin web server (v1.4.1 codename Chromeo)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4567, CTRL+C to stop
xxx.rb file
require 'Thin'
rackup_file = "config.ru"
argv = ARGV
argv << ["-R", rackup_file ] unless ARGV.include?("-R")
argv << ["-e", "production"] unless ARGV.include?("-e")
puts argv.flatten
Thin::Runner.new(argv.flatten).run!
config.ru file
require 'sinatra'
require 'sinatra/base'
class SingingRain < Sinatra::Base
get '/' do
return 'hello'
end
end
SingingRain.run!
#\ -p 8000
put this at the top of the config.ru
Your problem is with the line:
SingingRain.run!
This is Sinatra’s run method, which tells Sinatra to start its own web server which runs on port 4567 by default. This is in your config.ru file, but config.ru is just Ruby, so this line is run as if it was in any other .rb file. This is why you see Sinatra start up on that port.
When you stop this server with CTRL-C, Thin will try to continue loading the config.ru file to determine what app to run. You don’t actually specify an app in your config.ru, so you’ll see something like:
^C>> Stopping ...
== Sinatra has ended his set (crowd applauds)
/Users/matt/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/builder.rb:129:in `to_app': missing run or map statement (RuntimeError)
from config.ru:1:in `<main>'
...
This error is simply telling you that you didn’t actually specify an app to run in your config file.
Instead of SingingRain.run!, use:
run SingingRain
run is a Rack method that specifies which app to run. You could also do run SingingRain.new – Sinatra takes steps to enable you to use just the class itself here, or an instance.
The output to this should now just be:
>> Thin web server (v1.4.1 codename Chromeo)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:8000, CTRL+C to stop
You don’t get the == Sinatra/1.3.2 has taken the stage on 4567 for production with backup from Thin message because Sinatra isn’t running its built in server, it’s just your Thin server as you configured it.
in your config.ru add
set :port=> 8000
Also i would highly suggest using Sinatra with something like passenger+nginx which makes deploying to production a breeze. But You need not worry about this if you are going to deploy to heroku.

How to write a small ruby web server?

I have a ruby script that also needs to serve a few static files in a directory (such as an index.html, CSS and JS directories). What is the best way to write a little inline web server to serve these files?
Solution:
require 'webrick'
web_server = WEBrick::HTTPServer.new(:Port => 3000, :DocumentRoot => Dir.pwd + '/web')
trap 'INT' { web_server.shutdown }
web_server.start
Or add this to your .bash_profile for an easy way to serve up the files in any directory:
alias serve="ruby -rwebrick -e\"s = WEBrick::HTTPServer.new(:Port => 3000, :DocumentRoot => Dir.pwd); trap('INT') { s.shutdown }; s.start\""
You can use the simplest ruby HTTP server you can find:
ruby -run -e httpd . -p 5000
It will serve content from the running directory on port 5000.
If you're looking for something pure-Ruby and simple, WEBrick is a good choice. Because it is pure-Ruby, it won't go very fast.
Mongrel is partially implemented in C and Ruby and is better for performance than WEBrick. (The Ruby on Rails development mode will use Mongrel in preference to WEBrick if Mongrel is installed.)
If you'd like your server to scale better than either of WEBrick or Mongrel, then thin is probably the choice -- it glues Mongrel together on top of EventMachine to scale further than the other, simpler, systems can scale.
Nothing will quite replace running a full-blown web server such as nginx, but integrating that into your application is significantly more work for you and your users.
As #sarnold mentioned that thin is a good server, rack will use thin with a very high priority. And bellow is a one line way to go if you have the rack gem installed:
rackup -b "use Rack::Static, :index => 'index.html'; run Rack::File.new('.')"
If there's no 'index.html' in the current directory, the directory contents will be listed.
Have you looked at Sinatra?
It might be what you're looking for.

Ruby net/ping returning false for google? (Works from command-line)

I can ping google from my local machine, but can anyone tell me why I might be getting "false" when I run the following in IRB on the same machine? Really frustrating as a ping is supposed to be the most simple network op and I just can't get it to work!
1.9.2-p290 :001 > require "net/ping"
=> true
1.9.2-p290 :003 > pinger = Net::Ping::External.new("http://www.google.com")
=> #<Net::Ping::External:0x88eac30 #host="http://www.google.com", #port=7, #timeout=5, #exception=nil, #warning=nil, #duration=nil>
1.9.2-p290 :004 > pinger.ping
=> false
1.9.2-p290 :005 >
The following is not a valid host/domain name (although it is a valid URL):
http://www.google.com
Thus, the DNS resolution will fail and, having no target IP, no ping can be sent.
I'm sure you didn't use that exact host for the command-line ping :) As Gareth notes, doing so would look similar to:
$ ping http://www.google.com
ping: cannot resolve http://www.google.com: Unknown host
A "normal ping", which is being attempted here, and an "HTTP ping" are different. Contrast this usage with Net::Ping::HTTP, which does take a URL, for instance.
Happy coding.
(Either "google.com" or "www.google.com" would be suitable host names.)
If you're trying to check if a site is up then I wouldn't use ping. Ping will tell you if the host is up (unless a router or firewall is blocking ICMP), but it won't tell you if your web server or web app is responding properly.
If that's the case, I'd recommend Net::HTTP from the standard library, or any of the other HTTP libraries. One way to do it is:
def up?(site)
Net::HTTP.new(site).head('/').kind_of? Net::HTTPOK
end
up? 'www.google.com' #=> true

How to get ip address, referer, and user agent in ruby?

I want to log user's ip address, referer, and user agent.
In PHP, I can get them from the following variables:
$_SERVER['REMOTE_ADDR']
$_SERVER['HTTP_REFERER']
$_SERVER['HTTP_USER_AGENT']
How to get them in ruby?
PHP is embedded in a web server. Ruby is a general-purpose language: if you need a web server context, you'll have to install it yourself. Fortunately, it's easy.
One of the easiest ways to get started is with Sinatra. Install the gem:
gem install sinatra
Then create myapp.rb:
require 'sinatra'
get '/' do
request.user_agent
end
Start up the web server:
ruby -rubygems myapp.rb
Visit Sinatra's default URL: http://localhost:4567/
Et voilà.
You need the array request.env
request.env['REMOTE_ADDR']:
I'm assuming you by ruby you mean ruby on rails, the following link shows you how to access them:
http://techoctave.com/c7/posts/25-rails-request-environment-variables

Passing options to rackup via a Sinatra application

I'm new to ruby, learning Sinatra. While creating a Sinatra site by requiring 'sinatra' and setting up the routes directly under is pretty easy and rather well documented, creating an application by requiring 'sinatra/base' and writing a class that inherits from 'Sinatra::Base', while still relatively easy, is very poorly documented (maybe because it's a pretty recent feature of Sinatra).
And that's exactly what I am doing. I am not having too much trouble on the Sinatra part, however I am having a bit of trouble on the rackup/thin/server part. Apparently there are two ways to deploy the application: using Sinatra itself (using the run! method) and using a rackup file (typically config.ru).
Using Sinatra's run! method is extremely intuitive and works like a charm, but apparently it doesn't work if I want to deploy my app on heroku. As a matter of fact, almost all the Sinatra apps that I have encountered on GitHub use a config.ru file.
Using a rackup file might be equally intuitive, but I can't manage to understand how to pass options from the Sinatra app to the server (ir: the port). I tried to merge options to rackup's default options array:
MyApp::App.default_options.merge!(
:run => false,
:env => :production,
:port => 4567
)
run MyApp::App
by adding options directly to the app:
MyApp::App.set :port, 4567
MyApp::App.set :run, false
MyApp::App.set :env, :production
run MyApp::App
by setting options from within the application class:
module MyApp
class App < Sinatra::Base
set :port, 4567
set :run, false
set :env, :production
# ...
# config.ru
require 'app'
run MyApp::App
All the methods above failed, either by showing error messages or by just not taking any of the options into consideration. So is there any way to pass options to rackup/thin/the sever via a Sinatra app when using a rackup file? Or the options in questions should be passed directly to rackup/thin/the sever via command-line options?
As a reference to the problem, here is the little Sinatra application I am building: https://github.com/AzizLight/Wiki/
You're actully going to pass options to thin on the command line directly or via a configuration file. See all options:
$ thin -h
For production, use a configuration file:
$ thin -C thin-production.yml -R config.ru start
Here is an example thin-production.yml file:
---
address: localhost
port: 3020
servers: 4
max_conns: 1024
max_persistent_conns: 512
timeout: 30
environment: production
pid: tmp/pids/thin-production.pid
log: log/thin-production.log
daemonize: true
I know I'm resurrecting an ancient question here, but I came across another useful solution not yet mentioned. As stated in this rack wiki tutorial:
the first line starting with #\ is treated as if it was options, allowing rackup arguments to be specified in the config file.
So if you wanted to set your host to 0.0.0.0 and port to 5656, you would add the following line to the beginning of your config.ru file:
#\ -o 0.0.0.0 -p 5656

Resources