xx execs commands for you in your Docker Compose projects

I usually work on problems that are anything but straightforward – such as fighting disinformation – which typically require solutions that are anything but straightforward. Every so often though, you encounter a tiny problem that only needs a tiny fix.
Executing commands in a running Docker container is one such tiny problem. It’s
not hard. If you use Docker Compose you can just type docker compose exec,
give it a service name and a command, and you’re done. If that feels like too
much typing, you can make an alias or use your shell history.
That’s still too much typing for me. It doesn’t help that I have to deal with
multiple microservice macaroni architectures and often have to switch between
projects that use different service names. In one project the main service might
be called backend, in another app, and in a third it might be something like
newsspeak. I got tired of typing the right service names all the time,
so .
xx tries to find the container you’re most likely to want to run commands in.
This is usually a container that is built using from source, i.e. defined with a
build: in the Compose file rather than pulled as an image. xx will pass
whatever command you have provided on to that container.
For example, let’s take a look at the following Compose file.
This file contains two services: million-dollar-app, which we are developing,
and a database. If million-dollar-app is a Node.js app, normally you would
run something like this:
With xx, you simply run:
Often I just want a shell. By default, if you don’t provide any arguments to
xx, it will try to run bash. So to open a shell in the million-dollar-app
container all you have to do is run:
But what if your Compose file has more than one service that you build yourself?
In this case xx will prompt you to choose the container that should execute
the command:
If you’d like to try it out yourself, you can! I have published the entire
200-line script as a Gist. There’s no installer. Download it, make it
executable and put it somewhere in your PATH like /usr/local/bin, and you’re
good to go.

