Digital Adventures

ArchLinux, Ruby, Rails, OpenSource

Local Wildcard Domains for Web Development

Web developers quickly experience the pain of having to browse to localhost:[port] for each and every project they develop locally. The major issue for me was that my browser history for those URLs quickly became cluttered with all kinds of routes mixed from different projects.

Unique ports

Some work around this by assigning different ports for different projects but localhost:3001 isn’t very verbose on what project is in question.

lvh.me

Another approach is using a domain like lvh.me (local virtual host) kindly provided by a developer named Levi Cook. He simply created a DNS entry for *.lvh.me that points straight home: to 127.0.0.1. While this is great and allows us to use domains like [project_name].lvh.me for nice, verbose naming of projects it has a major drawback: It’s not usable offline. Arguably a webdeveloper almost always needs a connection to the internet (cough stackoverflow cough). Still, I don’t like the idea of being dependend on an external service for my local development environment.

Local DNS server + nginx

Despite of not quite being zero config this approach suits me best. It’s completely local and very flexible: I set up dnsmasq as a local DNS server, made it resolve *.dev to localhost and set up nginx to proxy requests to certain subdomains to certain ports on my machine. Here’s how:

Install dnsmasq and edit /etc/dnsmasq.conf. Add the following line:

1
address=/dev/127.0.0.1

Start dnsmasq and set it to start on boot:

1
2
systemctl start dnsmasq
systemctl enable dnsmasq

Now tell your network manager to use localhost as the primary nameserver. If you’re using dhcp your network manager or dhcpcd will overwrite /etc/resolv.conf. I created a file /etc/resolv/etc/resolv.conf.head whith the line

1
nameserver 127.0.0.1

dhcpcd respects this and prepends the generated resolv.conf with the content of the file.

Now that the dns server is set up install nginx and create a file /etc/nginx/sites-available/lvh.conf with the following or similar content:

/etc/nginx/sites-available/lvh.conf (lvh.conf) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
  listen 80;
  server_name *.rails.dev;

  access_log /dev/null;
  error_log /dev/null;

  location / {
    proxy_read_timeout 300;
    proxy_connect_timeout 300;
    proxy_redirect     off;

    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_set_header   Host              $http_host;
    proxy_set_header   X-Real-IP         $remote_addr;

    proxy_pass http://127.0.0.1:3000;
  }
}

In the same manner you can go and set up server blocks for sinatra, padrino, etc. using their respective default ports in the proxy_pass directive.

Create a symbolic link from the config file to /etc/nginx/sites-enabled/ and source it by adding

1
include sites-enabled/*.conf;

to the http block in /etc/nginx/nginx.conf.

Start and enable nginx and you should be good to go. Browsing to myproject.rails.dev will be resolved to 127.0.0.1 by dnsmasq and proxied to 127.0.0.1:3000 by nginx. Local virtual host goodness!

Comments