We recently had a Heroku support ticket where a user needed to modify their DNS lookup inside their app:
We’re connecting to an external API that requires a custom DNS entry. Locally, we modify our /etc/hosts file. How can we do this inside our app?
Modifying your /etc/hosts
file is a common process for tweaking your local DNS lookup. Your machine will first check this file for any custom entries before proceeding to find the host address on your remote DNS server (usually provided by your ISP).
However, while modifying the /etc/hosts
file on a remote server will work as well, this decreases the ability for your app to remain portable. In addition, this may create confusion for other team members that aren’t aware that you’ve modifed this file. Instead, let’s make the change inside our app using the Ruby standard library.
resolv.rb
is a pure-Ruby DNS implementation, and it’s actually much better performance-wise when app concurrency grows. The resolv-replace.rb
part replaces the default Ruby DNS resolution (e.g. system DNS) with resolv.rb
.
To implement, we first require “resolv-replace”, then create a Resolv::Hosts resolver and a regular DNS resolver. That way, the app will will check the hosts first, then fallback to real DNS.
Let’s start by adding our entry to a custom_hosts
file within our app:
You can now test this out in an irb
session:
You can now test the URL’s and ensure the DNS lookup behaves as necessary:
As you can see above, the DNS for my.customserver.com
resolves correctly as 127.0.0.1
.
We now have custom DNS information within our app, instead of needing to modify your system’s /etc/hosts
file. This allows you to keep this vital information contained within your app and under source control.
NOTE: using resolv.rb can cause some unwanted side effects like this one. Please make sure to test your implementation thoroughly!
Writer. Musician. Adventurer. Nerd.
Purveyor of GIFs and dad jokes.