📭 Use 'http://local.dev' instead of localhost
- Published on
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.
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.