xx execs commands for you in your Docker Compose projects
This is a short blog post about a short Perl script that I wrote to execute commands in running Docker Compose containers.
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 I wrote a small utility called xx.
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.
services: million-dollar-app: build: . depends_on: - database volumes: - .:/app
database: image: mysql:latestThis 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:
docker compose exec million-dollar-app npm iWith xx, you simply run:
xx npm iOften 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:
xxBut what if your Compose file has more than one service that you build yourself?
services: frontend: build: context: frontend volumes: - ./frontend:/app
backend: build: context: backend depends_on: - database volumes: - ./backend:/app
database: image: mysql:latestIn this case xx will prompt you to choose the container that should execute the command:
$ xx composer installWhere should 'composer install' be executed?1. frontend2. backendEnter the number of your choice: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.