1. Introduction

When we need to test an app that serves multiple subdomains, we have to set up a local environment that enables this. We need a way to resolve requests made to all subdomains of a given domain to the local machine’s IP (127.0.0.1).

In this tutorial, we’ll look at multiple ways to achieve this.

2. Modifying /etc/hosts

Let’s say we want to point multiple subdomains of a domain (a.localhost.com, b.localhost.com, etc.) to 127.0.0.1. We can make use of the special /etc/hosts file. The /etc/hosts is a particular file in Linux that we can use to resolve hardcoded domain names to IP addresses, even before a DNS lookup. To point to a.localhost.com and b.localhost.com, we need to add the following lines to /etc/hosts:

127.0.0.1        a.localhost.con
127.0.0.1        b.localhost.com

Opening either subdomains on the browser would show the expected web page served by the local application server. We must note that, with this method, it is impossible to define wildcard subdomains such as *.localhost.com in order to point all subdomains of localhost.com to the required IP. Instead, we’ll need to add one line each for every subdomain we need.

3. Using dnsmasq

dnsmasq is a utility that provides networking-related services such as DNS caching and DHCP server, among other things.

To use dnsmasq, we first need to install it and disable other name resolution services such as systemd-resolved. The process for doing this varies across distributions, and we must note the procedure of the particular distribution we’re using before proceeding.

Once we have dnsmasq setup, we need to add the following line in the /etc/dnsmasq.conf file:

address=/localhost.com/127.0.0.1

This line instructs dnsmasq to resolve all subdomains of localhost.com to 127.0.0.1. If we visit any subdomain of localhost.com, such as whatever.localhost.com or 123456.localhost.com, it will resolve to 127.0.0.1. We’ll see the response from the application server running locally.

4. Using localhost as the Domain

We can use localhost as the domain for testing our application. On Linux systems, localhost and all its subdomains such as a.localhost, b.localhost, and anything.localhost resolve to 127.0.0.1 by default. Below, we’ll look at an example of a simple server built with Flask that can handle requests from multiple subdomains:

# app.py
from flask import Flask, request

app = Flask(__name__)

@app.route("/")
def hello():
    return request.host

if __name__=="__main__":
    app.run(host="127.0.0.1", port="80", debug=True, use_reloader=True)

We’ve configured the app to reply with the hostname through which we accessed it. When we run this, the app server starts listening on port 80, which is the default port for HTTP requests. Now, we’ll try sending HTTP requests to some subdomains of localhost and observe the responses:

$ curl localhost
localhost

$ curl abc.localhost
abc.localhost

$ curl a123.localhost
a123.localhost

$ curl a.local
curl: (6) Could not resolve host: a.local

We see the expected response for names ending with .localhost. For production purposes, it is common to have a reverse proxy or a web server such as NGINX or Apache listening on port 80. We can also configure these applications to accept requests from all domain subdomains. We can change the application logic based on the subdomain we accessed the site from in our application code.

5. Conclusion

In this tutorial, we looked at three ways to resolve all subdomains of a given domain to the local IP address. Each of them has its advantages and drawbacks.