Three months ago I wrote an article entitled "Is Fig Docker's missing link?" It wasn't, quite, and I abandoned my attempt to move off of a single Vagrant VM and onto a super-clean Docker-powered development environment. My discovery of Skydock has reeled me back in.
First, some background - my experience of getting a complete development environment (Nginx, Postgres, Redis, Memcache, ElasticSearch and a Django app) running on Docker has not been a success. Our Trello card relating to the subject is now four months old, and has moved progressively from "In progress" to "Blocked" to "Parked" (or 'the graveyard', as it has become known). It ended with the following comment:
Giving up. This is ridiculous. Docker containers are assigned random IPs on startup, and that IP is then added to other containers as an environment variable, if they 'link' to that container. So, in our case, Nginx would like to speak to the app, so it links to the app, and when the Nginx container runs, it gets a new env var, APP_WEB_1_ADDR, which contains the IP... (and other vars for port, scheme, etc.)
There is no way to get that env var into Nginx's configuration. No way. It cannot be done. You cannot ask Nginx to proxy content to $APP_WEB_1_ADDR. The only way to make it work is to set up a DNS server, and use host names.
I am done.
I set out this weekend to write a series of linked posts on my experience, and why Docker may not be suitable to running a "developer's" environment (as opposed to a "development" environment - a distinction I will explain in a future post). I spent time thinking about this problem, and the other issue, which is that the linking of containers only works if it is done in the correct order. If you decide to restart / rebuild your database container (for instance, to reset the data to a known state), and the assigned IP changes, your downstream App container will no longer link to the correct container.
It occurred to me that the best solution would be for Docker itself (the daemon) to run a lightweight DNS server, similar to the way that most web frameworks can run a lightweight web/app server, that would resolve container names / IP addresses using standard DNS resolution. New containers would register themselves with the Docker DNS on start/stop, and there would be some deterministic domain name scheme, that would allow you to put fixed names into your configuration scripts (as opposed to environment variables, which need expansion). That way, in the example above, the Nginx container would speak to the app container as "app.dev", and the Django app configuration could include "redis.dev", "memcached.dev" and so on. These would always resolve to the correct IP address, using standard DNS name resolution.
Which brings us to the punchline - Skydock - "Automagic Service Discovery for Docker (via DNS)".
Skydock does exactly what it says - it's a great solution, it runs (natch) as a Docker container itself, and better than that, the creator, Michael Crosby, is a Docker employee. I speculated in my previous article on whether Docker would be introducing container orchestration features such as those supported by Fig - and this seems to confirm it.
Michael Crosby, I salute you.
(More technical details on how to run a developer's environment using Docker, and Fig, and Skydock, coming soon.)