An Idiosyncratic Blog

📭 Use 'http://local.dev' instead of localhost

Published on
3 minutes read

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. 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
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 may have 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 loop-back 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,

##
# Host Database
#
# localhost is used to configure the loop-back 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

# Custom domain mapping
127.0.0.1    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

What about ports?

Most applications usually run on a custom port, for example, port 3000 for React apps. What happens if we add 127.0.0.1:3000 instead of 127.0.0.1 to the hosts file?

Unfortunately, it doesn't work. The hosts file only deals with hostname, not ports.

Using a Reverse Proxy

As I mentioned above, things aren't 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 web server running on 3000 port.

Checkout the article, Running Multiple Apps on a single port using Docker, which explains how I run multiple applications with Docker with nginx as a reverse proxy.