Fast development environments

Update from 2023: I have long since stopped using this mechanism for

Setting up new hosts entries for every different web site that you develop is hard. This workflow allows you to completely automate it. First thing you’ll want to do is setup a wildcard DNS record that points to your host. This allows you to dynamically setup new development websites without having create new DNS records for each one of them. I created a fake internal-only TLD on my local network’s DNS server that automatically returns the IP address of my development VM for any query to *.devvm. If you don’t have access to that, you could re-use an actual domain and automatically forward something like * to the VM. For example, I have the ASUS RT-AC68U router for my personal network. So I SSH’d to the router, typed vi /etc/dnsmasq.conf, then appended:


then ran:

killall dnsmasq && dnsmasq –log-async

Then you should be able to resolve *.devvm on any host on the local network. Next you’re going to want to setup NGINX on your dev machine. Just install the latest version using:

sudo apt-get install nginx docker

NGINX will bind to port 80 and automatically forward HTTP requests to the correct web app. Then to automatically configure the site bindings in NGINX, I use a tool called docker-gen to automatically listen to Docker events and reload NGINX when I start and stop Docker containers. Then To run Docker-gen I do:

./docker-gen -only-exposed -watch -notify “/usr/sbin/service nginx reload” nginx.tmpl /etc/nginx/sites-enabled/docker_autoconf

The nginx.tmpl file can be found below. Any Docker container that has the VIRTUAL_HOST environmental variable will get registered in NGINX as a web site. docker-compose.yml:

  build: .
  command: "/bin/sh -c 'rm -f tmp/pids/ && cat && rails s -b'"
    - .:/rails-app
    - 3000
    RAILS_ENV: development
    VIRTUAL_HOST: certmgr.devvm


{{ range $host, $containers := groupBy $ “Env.VIRTUAL_HOST” }} upstream {{ $host }} { {{ range $index, $value := $containers }} {{ with $address := index $value.Addresses 0 }} server {{ $address.IP }}:{{ $address.Port }}; {{ end }} {{ end }} }

server { gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

server\_name {{ $host }};

location / {
    try\_files $uri @ruby;

location @ruby {
    proxy\_pass http://{{ $host }};
    include /etc/nginx/proxy\_params;

} {{ end }}

Copyright - All Rights Reserved


Comments are currently unavailable while I move to this new blog platform. To give feedback, send an email to adam [at] this website url.