Getting the Hostname or IP in Ruby on Rails

Viewed 99630

I'm in the process of maintaining a Ruby on Rails app and am looking for an easy way to find the hostname or IP address of the box I'm on (since it's a VM and new instances may have different hostnames or IP addresses). Is there a quick and easy way to do this in Ruby on Rails?

Edit: The answer below is correct but the clarification Craig provided is useful (see also provided link in answer):

The [below] code does NOT make a connection or send any packets (to 64.233.187.99 which is google). Since UDP is a stateless protocol connect() merely makes a system call which figures out how to route the packets based on the address and what interface (and therefore IP address) it should bind to. addr() returns an array containing the family (AF_INET), local port, and local address (which is what we want) of the socket.

12 Answers

From coderrr.wordpress.com:

require 'socket'

def local_ip
  orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true  # turn off reverse DNS resolution temporarily

  UDPSocket.open do |s|
    s.connect '64.233.187.99', 1
    s.addr.last
  end
ensure
  Socket.do_not_reverse_lookup = orig
end

# irb:0> local_ip
# => "192.168.0.127"

Try this:

host = `hostname`.strip # Get the hostname from the shell and removing trailing \n
puts host               # Output the hostname

This IP address used here is Google's, but you can use any accessible IP.

require "socket"
local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}

The accepted answer works but you have to create a socket for every request and it does not work if the server is on a local network and/or not connected to the internet. The below, I believe will always work since it is parsing the request header.

request.env["SERVER_ADDR"]

You will likely find yourself having multiple IP addresses on each machine (127.0.0.1, 192.168.0.1, etc). If you are using *NIX as your OS, I'd suggest using hostname, and then running a DNS look up on that. You should be able to use /etc/hosts to define the local hostname to resolve to the IP address for that machine. There is similar functionality on Windows, but I haven't used it since Windows 95 was the bleeding edge.

The other option would be to hit a lookup service like WhatIsMyIp.com. These guys will kick back your real-world IP address to you. This is also something that you can easily setup with a Perl script on a local server if you prefer. I believe 3 lines or so of code to output the remote IP from %ENV should cover you.

try: Request.remote_ip

remote_ip()

Determine originating IP address. REMOTE_ADDR is the standard but will fail if the user is behind a proxy. HTTP_CLIENT_IP and/or HTTP_X_FORWARDED_FOR are set by proxies so check for these if REMOTE_ADDR is a proxy. HTTP_X_FORWARDED_FOR may be a comma- delimited list in the case of multiple chained proxies; the last address which is not trusted is the originating IP.

Update: Oops, sorry I misread the documentation.

Related