For configuration, we separate the application and the config files into two separate containers. The config files are provided through a shared volume to the application. This model is definitely odd. However, it's allowed us to decouple our application and our configuration and to swap out configurations. With this in mind, it's more declarative because we specify "run this application with this configuration unit" rather than "here's how you get yourself started". See the Radial project for our inspiration[1]
We've found that this approach has generalized so far. For example, setting up a Cassandra cluster is often a real PITA to configure since you need the seed IPs up front. Our configuration container manages the dance by registering and pulling the IPs from Consul (etcd would work fine too). Perhaps a bit of smoke-and-mirrors, but it's achieved being able to spin up a properly-configured Cassandra cluster without needing to manually specify who's in the cluster.
The Docker folks get a point for bootstrapping a familiar user interface: git. Our non-dev coworkers are competent enough with git, and they felt comfortable drawing analogies between the two. They pull the image (from our private Docker registry), run the container, make some changes, build, run, repeat. Very similar to pull, check out, commit, etc in git.
The only pain I've had is the silly flags for 'docker run'. Ugh. Before I told them to make aliases, there were all sorts of complains when they forgot '-it' and '--rm'. I think '-it' should be the default, and possibly '--rm' as well, with switches to toggle them off. Oh well.
Yes, very much so. In fact, our goal is to have NixOS based containers. Right now, we're using Debian as the base image, and there's /no/ guarantee that the versions of software installed are consistent (since Docker caches based on the line in a Dockerfile, rather than what's actually installed).
With Nix, we can have version guarantees in all of our Docker images--including the cached images.
* Sanity in our environments. We know exactly what goes into each and every environment, which are specialized based on the one-app-per-container principle. No more asking "why does software X build/execute on machine A and not machines B-C?"
* Declarative deployments. Using Docker, Core OS, and fleet[1], this is the closest solution I've found to the dream of specifying what I want running across a cluster of machines, rather than procedurally specifying the steps to deploy something (e.g. Chef, Ansible, and the lot). There's been other attempts for declarative deployments (Pallet comes to mind), but I think Docker and Fleet provide even better composability. This is my favorite gain.
* Managing Cabal dependency hell. Most of our application development is in Haskell, and we've found we prefer specifying a Docker image than working with Cabal sandboxes. This is equally a gain on other programming platforms. You can replace virtualenv for Python and rvm for Ruby with Docker containers.
* Bridging a gap with less-technical coworkers. We work with some statisticians. Smart folks, but getting them to install and configure ODBC & FreeTDS properly was a nightmare. Training them in an hour on Docker and boot2docker has saved so much frustration. Not only are they able to run software that the devs provide, but they can contribute and be (mostly) guaranteed that it'll work on our side, too.
I was skeptical about Docker for a long time, but after working with it for the greater part of the year, I've been greatly satisfied. It's not a solution to everything—I'm careful to avoid hammer syndrome—but I think it's a huge step forwards for development and operations.
Addendum: Yes, some of these gains can be equally solved with VMs, but I can run through /dozens/ of iterations of building Docker images by the time you've spun up one VM.
Learning Finnish involves learning two dialects, spoken and written, and the spoken dialect can vary considerably even between cities 200km apart. But it's an incredibly fun language to learn. Very logically constructed, few(er) exceptions to the rules, and if you can say it, you can spell it!