📭 Use 'http://local.dev' instead of localhostMay 29, 2021Networking 472 words

In my last blog post titled, Running Multiple Apps on a single port using Docker, I used http://local.dev instead of http://localhost. I find it to be cleaner when presenting a product demo on my local machine to a wider audience. And because I use a reverse proxy to manage all applications, I don’t need to remember the port value always. I can just type in http://local.dev/app-name and it just works. (provided it’s configured in the docker compose file).

Another use-case could be that one needs to access an asset or call an API from a domain which has CORS enabled for whitelisted domains only. For example, let’s consider the case of a web application that uses a lambda function to retrieve images from somewhere. Let’s also consider that the lambda function only allows requests from dashboard.hackerman.io. In this case, the subdomain is dashboard and the domain is hackerman.io.

Impossible? Well, not quite.

Don't say impossible

Editing the Host file

On Mac and Linux systems, the file is at /etc/hosts. On Windows PC, it’s at C:\Windows\System32\drivers\etc.

Fire up a terminal and edit the file.

sudo vim /etc/hosts

⚠️ You’re required to enter your password because you’re changing a system file!

The file will already have a couple of lines:

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1	localhost
255.255.255.255	broadcasthost
::1             localhost
# Added by Docker Desktop
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section

Now add a new entry to the last line,

127.0.0.1:3000    dashboard.hackerman.io

save the file, and that’s it. Now when you enter dashboard.hackerman.io, you are redirected to the application which is running on port 80. This works because of how DNS resolution works on the local machine. If the first preference is given to /etc/hosts then the override works.

ℹ️

  • On MacOS, the DNS lookup is done through the service mDNSResponder service which is running as a socket at /var/run/mDNSResponder.
  • /etc/nsswitch.conf is the default file for domain name resolution these days on Linux Machines
  • Windows has had so many versions over the years, it depends on the version of Windows being used

Adding a Port

Most applications these run on a default port, for example, port 3000. One might wonder if we can also accomplish this with /etc/hosts. For example, can we add the following line to the hosts file:

127.0.0.1:3000    dashboard.hackerman.io

Unfortunately, we can’t. The hosts file only deals with hostnames, not ports.

Using a Reverse Proxy

As I mentioned above, things are not always Impossible. We can use a reverse proxy like nginx to forward requests to the correct service. A simple /etc/nginx/conf.d would look like this:

server {
    listen 80;

    server_name hackerman.io;

    location / {
        proxy_pass http://dashboard.hackerman.io:3000/;
    }
}

When we use this config together with:

127.0.0.1:3000    dashboard.hackerman.io

in /etc/hosts, nginx will receive our requests for dashboard.hackerman.io and direct those to the webserver running on 3000 port.

ℹ️ To make your life easier, and run multiple applications with Docker with nginx as a reverse proxy, checkout the blog post Running Multiple Apps on a single port using Docker.

Mapping hostnames to IP-addresses in /etc/hosts can be very useful for testing purposes. Unfortunately, we can’t map hostnames including port numbers this way. We can however get around this issue by configuring a reverse proxy using nginx.