If you are a docker-compose user, as I am, you may be missing one feature: exec—spawning arbitrary commands in already running containers.

Instead of doing this:

$ docker exec -ti $container bash

you should be able do the same with docker-compose itself:

$ docker-compose exec web bash

Usually when you wanted to do such thing, you had to:

  1. Type docker exec -ti
  2. Now, the container name
  3. ^c
  4. docker ps, I forgot to name my container again!
  5. ba3f7099b709, ugh
  6. docker exec -ti, once again, copy-paste that ID, write bash and 30 seconds later:
[root@ba3f7099b709 /] # █

That workflow isn’t very ideal. So I realized I wanted to implement the feature (especially when there already was an issue open, with tons of +1 and not even a single promise of someone working on it).

Easy Start

In September, I cloned compose and started working on the code. I managed to have a working prototype very soon:

$ docker-compose exec web ls
bin  boot  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

Time to Go Interactive

That’s when all the fun started.

Running simple, non-interactive commands is pretty trivial. Just create an exec object via engine’s API, start it, and collect results. Easy.

When you want an interactive session, it’s getting a bit more complex than a simple request/response over HTTP. That’s when dockerpty comes into the play. It is able to attach to the process via engine’s API, send input, receive output and display it. Brief code-browsing revealed there’s tons of work ahead:

  • I had to rewrite big part of existing codebase.
  • I had to change existing API and add a new one.
  • Cherry on top: the tests didn’t work and I had to fix those.

Even dockerpty didn’t have all the bits to write proper exec support for interactive commands. I had to go deeper: improve python’s API client—docker-py. Luckily that patch was pretty easy: just return socket directly, not a generator.

The patch for dockerpty turned out to be super-complex. In the end, it took me more than 5 months to get the former compose patch merged.

Enjoy docker-compose exec once 1.7 is out! Happy execing!